From 175197da8ea43335df3daeba4c6296fcd83a057c Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Thu, 10 Nov 2016 13:31:25 +0100 Subject: Post split cleanup - change groupIds - change packages - update poms Change-Id: I343c5a292a67de1dd50687870ca4ab5b7276e93e Signed-off-by: Maros Marsalek Signed-off-by: Marek Gradzki --- v3po/api/pom.xml | 5 +- v3po/pom.xml | 3 +- v3po/v3po2vpp/pom.xml | 8 +- .../java/io/fd/hc2vpp/v3po/AclWriterFactory.java | 58 ++++ .../fd/hc2vpp/v3po/DisabledInterfacesManager.java | 106 +++++++ .../hc2vpp/v3po/EgressIetfAClWriterProvider.java | 39 +++ .../hc2vpp/v3po/IngressIetfAClWriterProvider.java | 39 +++ .../hc2vpp/v3po/InterfacesStateReaderFactory.java | 187 ++++++++++++ .../io/fd/hc2vpp/v3po/InterfacesWriterFactory.java | 244 +++++++++++++++ .../SubinterfaceAugmentationWriterFactory.java | 158 ++++++++++ ...SubinterfaceStateAugmentationReaderFactory.java | 118 +++++++ .../main/java/io/fd/hc2vpp/v3po/V3poModule.java | 92 ++++++ .../v3po/VppClassifierHoneycombWriterFactory.java | 64 ++++ .../fd/hc2vpp/v3po/VppClassifierReaderFactory.java | 60 ++++ .../fd/hc2vpp/v3po/VppHoneycombWriterFactory.java | 81 +++++ .../v3po/VppStateHoneycombReaderFactory.java | 90 ++++++ .../fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java | 24 ++ .../hc2vpp/v3po/interfaces/EthernetCustomizer.java | 58 ++++ .../fd/hc2vpp/v3po/interfaces/GreCustomizer.java | 166 ++++++++++ .../v3po/interfaces/InterconnectionWriteUtils.java | 159 ++++++++++ .../v3po/interfaces/InterfaceCustomizer.java | 121 ++++++++ .../io/fd/hc2vpp/v3po/interfaces/L2Customizer.java | 89 ++++++ .../hc2vpp/v3po/interfaces/LoopbackCustomizer.java | 112 +++++++ .../hc2vpp/v3po/interfaces/ProxyArpCustomizer.java | 108 +++++++ .../hc2vpp/v3po/interfaces/RewriteCustomizer.java | 136 +++++++++ .../hc2vpp/v3po/interfaces/RoutingCustomizer.java | 122 ++++++++ .../v3po/interfaces/SubInterfaceCustomizer.java | 193 ++++++++++++ .../v3po/interfaces/SubInterfaceL2Customizer.java | 100 ++++++ .../fd/hc2vpp/v3po/interfaces/TapCustomizer.java | 182 +++++++++++ .../v3po/interfaces/VhostUserCustomizer.java | 157 ++++++++++ .../fd/hc2vpp/v3po/interfaces/VxlanCustomizer.java | 192 ++++++++++++ .../hc2vpp/v3po/interfaces/VxlanGpeCustomizer.java | 194 ++++++++++++ .../hc2vpp/v3po/interfaces/acl/IetfAclWriter.java | 106 +++++++ .../acl/common/AbstractIetfAclWriter.java | 251 +++++++++++++++ .../v3po/interfaces/acl/common/AceEthWriter.java | 85 ++++++ .../v3po/interfaces/acl/common/AceIp4Writer.java | 94 ++++++ .../v3po/interfaces/acl/common/AceIp6Writer.java | 99 ++++++ .../interfaces/acl/common/AceIpAndEthWriter.java | 129 ++++++++ .../v3po/interfaces/acl/common/AceWriter.java | 54 ++++ .../acl/common/AclTableContextManager.java | 53 ++++ .../acl/common/AclTableContextManagerImpl.java | 68 +++++ .../v3po/interfaces/acl/common/AclTranslator.java | 74 +++++ .../v3po/interfaces/acl/common/IetfAclWriter.java | 47 +++ .../interfaces/acl/common/Ip4AclTranslator.java | 149 +++++++++ .../interfaces/acl/common/Ip6AclTranslator.java | 182 +++++++++++ .../interfaces/acl/common/L2AclTranslator.java | 90 ++++++ .../v3po/interfaces/acl/common/PortPair.java | 126 ++++++++ .../interfaces/acl/egress/EgressIetfAclWriter.java | 120 ++++++++ .../interfaces/acl/egress/IetfAclCustomizer.java | 85 ++++++ .../acl/egress/SubInterfaceIetfAclCustomizer.java | 105 +++++++ .../v3po/interfaces/acl/ingress/AclCustomizer.java | 83 +++++ .../v3po/interfaces/acl/ingress/AclWriter.java | 73 +++++ .../interfaces/acl/ingress/IetfAclCustomizer.java | 89 ++++++ .../acl/ingress/IngressIetfAclWriter.java | 118 +++++++ .../acl/ingress/SubInterfaceAclCustomizer.java | 93 ++++++ .../acl/ingress/SubInterfaceIetfAclCustomizer.java | 108 +++++++ .../v3po/interfaces/ip/Ipv4AddressCustomizer.java | 151 +++++++++ .../hc2vpp/v3po/interfaces/ip/Ipv4Customizer.java | 56 ++++ .../interfaces/ip/Ipv4NeighbourCustomizer.java | 126 ++++++++ .../fd/hc2vpp/v3po/interfaces/ip/Ipv4Writer.java | 108 +++++++ .../hc2vpp/v3po/interfaces/ip/Ipv6Customizer.java | 55 ++++ .../ip/SubInterfaceIpv4AddressCustomizer.java | 131 ++++++++ .../validation/SubnetValidationException.java | 50 +++ .../ip/subnet/validation/SubnetValidator.java | 80 +++++ .../v3po/interfaces/pbb/PbbRewriteCustomizer.java | 130 ++++++++ .../v3po/interfacesstate/EthernetCustomizer.java | 108 +++++++ .../hc2vpp/v3po/interfacesstate/GreCustomizer.java | 157 ++++++++++ .../interfacesstate/InterconnectionReadUtils.java | 125 ++++++++ .../v3po/interfacesstate/InterfaceCustomizer.java | 232 ++++++++++++++ .../interfacesstate/InterfaceDataTranslator.java | 287 +++++++++++++++++ .../hc2vpp/v3po/interfacesstate/L2Customizer.java | 116 +++++++ .../v3po/interfacesstate/ProxyArpCustomizer.java | 79 +++++ .../v3po/interfacesstate/RewriteCustomizer.java | 147 +++++++++ .../interfacesstate/SubInterfaceCustomizer.java | 264 ++++++++++++++++ .../interfacesstate/SubInterfaceL2Customizer.java | 93 ++++++ .../hc2vpp/v3po/interfacesstate/TapCustomizer.java | 143 +++++++++ .../v3po/interfacesstate/VhostUserCustomizer.java | 154 ++++++++++ .../v3po/interfacesstate/VxlanCustomizer.java | 162 ++++++++++ .../v3po/interfacesstate/VxlanGpeCustomizer.java | 168 ++++++++++ .../interfacesstate/acl/ingress/AclCustomizer.java | 118 +++++++ .../interfacesstate/acl/ingress/AclReader.java | 60 ++++ .../acl/ingress/SubInterfaceAclCustomizer.java | 120 ++++++++ .../interfacesstate/ip/Ipv4AddressCustomizer.java | 166 ++++++++++ .../v3po/interfacesstate/ip/Ipv4Customizer.java | 59 ++++ .../ip/Ipv4NeighbourCustomizer.java | 73 +++++ .../hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java | 84 +++++ .../v3po/interfacesstate/ip/Ipv6Customizer.java | 66 ++++ .../ip/SubInterfaceIpv4AddressCustomizer.java | 143 +++++++++ .../ip/dump/params/AddressDumpParams.java | 44 +++ .../pbb/PbbRewriteStateCustomizer.java | 57 ++++ .../InterfaceChangeNotificationProducer.java | 163 ++++++++++ .../io/fd/hc2vpp/v3po/util/SubInterfaceUtils.java | 52 ++++ .../vpp/ArpTerminationTableEntryCustomizer.java | 118 +++++++ .../fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java | 137 +++++++++ .../fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java | 129 ++++++++ .../v3po/vppclassifier/ClassifySessionReader.java | 207 +++++++++++++ .../v3po/vppclassifier/ClassifySessionWriter.java | 165 ++++++++++ .../v3po/vppclassifier/ClassifyTableReader.java | 171 +++++++++++ .../v3po/vppclassifier/ClassifyTableWriter.java | 149 +++++++++ .../vppclassifier/VppClassifierContextManager.java | 106 +++++++ .../VppClassifierContextManagerImpl.java | 181 +++++++++++ .../hc2vpp/v3po/vppclassifier/VppNodeReader.java | 45 +++ .../hc2vpp/v3po/vppclassifier/VppNodeWriter.java | 79 +++++ .../v3po/vppstate/BridgeDomainCustomizer.java | 181 +++++++++++ .../hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java | 165 ++++++++++ .../fd/hc2vpp/v3po/vppstate/VersionCustomizer.java | 82 +++++ .../honeycomb/translate/v3po/AclWriterFactory.java | 58 ---- .../translate/v3po/DisabledInterfacesManager.java | 106 ------- .../v3po/EgressIetfAClWriterProvider.java | 39 --- .../v3po/IngressIetfAClWriterProvider.java | 39 --- .../v3po/InterfacesStateReaderFactory.java | 187 ------------ .../translate/v3po/InterfacesWriterFactory.java | 245 --------------- .../SubinterfaceAugmentationWriterFactory.java | 158 ---------- ...SubinterfaceStateAugmentationReaderFactory.java | 118 ------- .../io/fd/honeycomb/translate/v3po/V3poModule.java | 92 ------ .../v3po/VppClassifierHoneycombWriterFactory.java | 66 ---- .../translate/v3po/VppClassifierReaderFactory.java | 60 ---- .../translate/v3po/VppHoneycombWriterFactory.java | 81 ----- .../v3po/VppStateHoneycombReaderFactory.java | 90 ------ .../translate/v3po/cfgattrs/V3poConfiguration.java | 24 -- .../v3po/interfaces/EthernetCustomizer.java | 58 ---- .../translate/v3po/interfaces/GreCustomizer.java | 166 ---------- .../v3po/interfaces/InterconnectionWriteUtils.java | 159 ---------- .../v3po/interfaces/InterfaceCustomizer.java | 121 -------- .../translate/v3po/interfaces/L2Customizer.java | 89 ------ .../v3po/interfaces/LoopbackCustomizer.java | 112 ------- .../v3po/interfaces/ProxyArpCustomizer.java | 108 ------- .../v3po/interfaces/RewriteCustomizer.java | 136 --------- .../v3po/interfaces/RoutingCustomizer.java | 122 -------- .../v3po/interfaces/SubInterfaceCustomizer.java | 193 ------------ .../v3po/interfaces/SubInterfaceL2Customizer.java | 100 ------ .../translate/v3po/interfaces/TapCustomizer.java | 182 ----------- .../v3po/interfaces/VhostUserCustomizer.java | 157 ---------- .../translate/v3po/interfaces/VxlanCustomizer.java | 192 ------------ .../v3po/interfaces/VxlanGpeCustomizer.java | 194 ------------ .../v3po/interfaces/acl/IetfAclWriter.java | 106 ------- .../acl/common/AbstractIetfAclWriter.java | 251 --------------- .../v3po/interfaces/acl/common/AceEthWriter.java | 85 ------ .../v3po/interfaces/acl/common/AceIp4Writer.java | 94 ------ .../v3po/interfaces/acl/common/AceIp6Writer.java | 99 ------ .../interfaces/acl/common/AceIpAndEthWriter.java | 129 -------- .../v3po/interfaces/acl/common/AceWriter.java | 54 ---- .../acl/common/AclTableContextManager.java | 53 ---- .../acl/common/AclTableContextManagerImpl.java | 68 ----- .../v3po/interfaces/acl/common/AclTranslator.java | 74 ----- .../v3po/interfaces/acl/common/IetfAclWriter.java | 47 --- .../interfaces/acl/common/Ip4AclTranslator.java | 149 --------- .../interfaces/acl/common/Ip6AclTranslator.java | 182 ----------- .../interfaces/acl/common/L2AclTranslator.java | 90 ------ .../v3po/interfaces/acl/common/PortPair.java | 126 -------- .../interfaces/acl/egress/EgressIetfAclWriter.java | 120 -------- .../interfaces/acl/egress/IetfAclCustomizer.java | 85 ------ .../acl/egress/SubInterfaceIetfAclCustomizer.java | 105 ------- .../v3po/interfaces/acl/ingress/AclCustomizer.java | 83 ----- .../v3po/interfaces/acl/ingress/AclWriter.java | 73 ----- .../interfaces/acl/ingress/IetfAclCustomizer.java | 89 ------ .../acl/ingress/IngressIetfAclWriter.java | 118 ------- .../acl/ingress/SubInterfaceAclCustomizer.java | 93 ------ .../acl/ingress/SubInterfaceIetfAclCustomizer.java | 108 ------- .../v3po/interfaces/ip/Ipv4AddressCustomizer.java | 151 --------- .../v3po/interfaces/ip/Ipv4Customizer.java | 56 ---- .../interfaces/ip/Ipv4NeighbourCustomizer.java | 126 -------- .../translate/v3po/interfaces/ip/Ipv4Writer.java | 108 ------- .../v3po/interfaces/ip/Ipv6Customizer.java | 55 ---- .../ip/SubInterfaceIpv4AddressCustomizer.java | 131 -------- .../validation/SubnetValidationException.java | 50 --- .../ip/subnet/validation/SubnetValidator.java | 80 ----- .../v3po/interfaces/pbb/PbbRewriteCustomizer.java | 130 -------- .../v3po/interfacesstate/EthernetCustomizer.java | 108 ------- .../v3po/interfacesstate/GreCustomizer.java | 157 ---------- .../interfacesstate/InterconnectionReadUtils.java | 125 -------- .../v3po/interfacesstate/InterfaceCustomizer.java | 232 -------------- .../interfacesstate/InterfaceDataTranslator.java | 287 ----------------- .../v3po/interfacesstate/L2Customizer.java | 116 ------- .../v3po/interfacesstate/ProxyArpCustomizer.java | 79 ----- .../v3po/interfacesstate/RewriteCustomizer.java | 147 --------- .../interfacesstate/SubInterfaceCustomizer.java | 264 ---------------- .../interfacesstate/SubInterfaceL2Customizer.java | 93 ------ .../v3po/interfacesstate/TapCustomizer.java | 143 --------- .../v3po/interfacesstate/VhostUserCustomizer.java | 154 ---------- .../v3po/interfacesstate/VxlanCustomizer.java | 162 ---------- .../v3po/interfacesstate/VxlanGpeCustomizer.java | 168 ---------- .../interfacesstate/acl/ingress/AclCustomizer.java | 118 ------- .../interfacesstate/acl/ingress/AclReader.java | 60 ---- .../acl/ingress/SubInterfaceAclCustomizer.java | 120 -------- .../interfacesstate/ip/Ipv4AddressCustomizer.java | 166 ---------- .../v3po/interfacesstate/ip/Ipv4Customizer.java | 59 ---- .../ip/Ipv4NeighbourCustomizer.java | 73 ----- .../v3po/interfacesstate/ip/Ipv4Reader.java | 84 ----- .../v3po/interfacesstate/ip/Ipv6Customizer.java | 66 ---- .../ip/SubInterfaceIpv4AddressCustomizer.java | 143 --------- .../ip/dump/params/AddressDumpParams.java | 44 --- .../pbb/PbbRewriteStateCustomizer.java | 57 ---- .../InterfaceChangeNotificationProducer.java | 163 ---------- .../vpp/ArpTerminationTableEntryCustomizer.java | 118 ------- .../translate/v3po/vpp/BridgeDomainCustomizer.java | 137 --------- .../translate/v3po/vpp/L2FibEntryCustomizer.java | 129 -------- .../v3po/vppclassifier/ClassifySessionReader.java | 207 ------------- .../v3po/vppclassifier/ClassifySessionWriter.java | 165 ---------- .../v3po/vppclassifier/ClassifyTableReader.java | 171 ----------- .../v3po/vppclassifier/ClassifyTableWriter.java | 149 --------- .../vppclassifier/VppClassifierContextManager.java | 106 ------- .../VppClassifierContextManagerImpl.java | 181 ----------- .../v3po/vppclassifier/VppNodeReader.java | 45 --- .../v3po/vppclassifier/VppNodeWriter.java | 79 ----- .../v3po/vppstate/BridgeDomainCustomizer.java | 181 ----------- .../v3po/vppstate/L2FibEntryCustomizer.java | 165 ---------- .../translate/v3po/vppstate/VersionCustomizer.java | 82 ----- .../translate/vpp/util/SubInterfaceUtils.java | 52 ---- .../hc2vpp/v3po/DisabledInterfacesManagerTest.java | 109 +++++++ .../java/io/fd/hc2vpp/v3po/V3poModuleTest.java | 96 ++++++ .../hc2vpp/v3po/interfaces/AclCustomizerTest.java | 156 ++++++++++ .../hc2vpp/v3po/interfaces/GreCustomizerTest.java | 197 ++++++++++++ .../v3po/interfaces/InterfaceCustomizerTest.java | 116 +++++++ .../v3po/interfaces/InterfaceTypeTestUtils.java | 40 +++ .../hc2vpp/v3po/interfaces/L2CustomizerTest.java | 150 +++++++++ .../v3po/interfaces/LoopbackCustomizerTest.java | 105 +++++++ .../v3po/interfaces/ProxyArpCustomizerTest.java | 97 ++++++ .../v3po/interfaces/RewriteCustomizerTest.java | 198 ++++++++++++ .../v3po/interfaces/RoutingCustomizerTest.java | 97 ++++++ .../interfaces/SubInterfaceCustomizerTest.java | 258 ++++++++++++++++ .../interfaces/SubInterfaceL2CustomizerTest.java | 109 +++++++ .../hc2vpp/v3po/interfaces/TapCustomizerTest.java | 129 ++++++++ .../v3po/interfaces/VhostUserCustomizerTest.java | 205 +++++++++++++ .../v3po/interfaces/VxlanCustomizerTest.java | 227 ++++++++++++++ .../v3po/interfaces/VxlanGpeCustomizerTest.java | 218 +++++++++++++ .../hc2vpp/v3po/interfaces/acl/AclWriterTest.java | 103 +++++++ .../interfaces/acl/common/AceEthWriterTest.java | 94 ++++++ .../interfaces/acl/common/AceIp4WriterTest.java | 189 ++++++++++++ .../interfaces/acl/common/AceIp6WriterTest.java | 200 ++++++++++++ .../acl/common/AceIpAndEthWriterTest.java | 123 ++++++++ .../acl/common/AceIpWriterTestUtils.java | 34 +++ .../acl/common/AclTableContextManagerImplTest.java | 62 ++++ .../v3po/interfaces/acl/common/PortPairTest.java | 114 +++++++ .../acl/egress/EgressIetfAclWriterTest.java | 151 +++++++++ .../acl/egress/IetfAclCustomizerTest.java | 114 +++++++ .../egress/SubInterfaceIetfAclCustomizerTest.java | 130 ++++++++ .../acl/ingress/IetfAclCustomizerTest.java | 205 +++++++++++++ .../acl/ingress/SubInterfaceAclCustomizerTest.java | 140 +++++++++ .../ingress/SubInterfaceIetfAclCustomizerTest.java | 155 ++++++++++ .../interfaces/ip/Ipv4AddressCustomizerTest.java | 338 +++++++++++++++++++++ .../interfaces/ip/Ipv4NeighbourCustomizerTest.java | 120 ++++++++ .../ip/SubInterfaceIpv4AddressCustomizerTest.java | 144 +++++++++ .../ip/subnet/validation/SubnetValidatorTest.java | 88 ++++++ .../interfaces/pbb/PbbRewriteCustomizerTest.java | 312 +++++++++++++++++++ .../interfacesstate/EthernetCustomizerTest.java | 90 ++++++ .../v3po/interfacesstate/GreCustomizerTest.java | 131 ++++++++ .../interfacesstate/InterfaceCustomizerTest.java | 200 ++++++++++++ .../InterfaceDataTranslatorTest.java | 55 ++++ .../v3po/interfacesstate/L2CustomizerTest.java | 145 +++++++++ .../interfacesstate/RewriteCustomizerTest.java | 114 +++++++ .../SubInterfaceCustomizerTest.java | 129 ++++++++ .../SubInterfaceL2CustomizerTest.java | 80 +++++ .../v3po/interfacesstate/TapCustomizerTest.java | 98 ++++++ .../interfacesstate/VhostUserCustomizerTest.java | 115 +++++++ .../v3po/interfacesstate/VxlanCustomizerTest.java | 133 ++++++++ .../interfacesstate/VxlanGpeCustomizerTest.java | 278 +++++++++++++++++ .../acl/ingress/AclCustomizerTest.java | 99 ++++++ .../acl/ingress/SubInterfaceAclCustomizerTest.java | 108 +++++++ .../ip/Ipv4AddressCustomizerTest.java | 284 +++++++++++++++++ .../interfacesstate/ip/Ipv4CustomizerTest.java | 44 +++ .../ip/SubInterfaceIpv4AddressCustomizerTest.java | 247 +++++++++++++++ .../pbb/PbbRewriteStateCustomizerTest.java | 35 +++ .../InterfaceChangeNotificationProducerTest.java | 112 +++++++ .../fd/hc2vpp/v3po/util/SubinterfaceUtilsTest.java | 32 ++ .../ArpTerminationTableEntryCustomizerTest.java | 171 +++++++++++ .../v3po/vpp/BridgeDomainCustomizerTest.java | 276 +++++++++++++++++ .../hc2vpp/v3po/vpp/L2FibEntryCustomizerTest.java | 190 ++++++++++++ .../vppclassifier/ClassifySessionReaderTest.java | 116 +++++++ .../vppclassifier/ClassifySessionWriterTest.java | 179 +++++++++++ .../vppclassifier/ClassifyTableReaderTest.java | 126 ++++++++ .../vppclassifier/ClassifyTableWriterTest.java | 181 +++++++++++ .../VppClassifierContextManagerImplTest.java | 163 ++++++++++ .../v3po/vppstate/BridgeDomainCustomizerTest.java | 47 +++ .../v3po/vppstate/L2FibEntryCustomizerTest.java | 124 ++++++++ .../v3po/vppstate/VersionCustomizerTest.java | 60 ++++ .../io/fd/hc2vpp/v3po/vppstate/VppStateTest.java | 326 ++++++++++++++++++++ .../v3po/DisabledInterfacesManagerTest.java | 109 ------- .../honeycomb/translate/v3po/V3poModuleTest.java | 96 ------ .../v3po/interfaces/AclCustomizerTest.java | 156 ---------- .../v3po/interfaces/GreCustomizerTest.java | 197 ------------ .../v3po/interfaces/InterfaceCustomizerTest.java | 116 ------- .../v3po/interfaces/InterfaceTypeTestUtils.java | 40 --- .../v3po/interfaces/L2CustomizerTest.java | 150 --------- .../v3po/interfaces/LoopbackCustomizerTest.java | 105 ------- .../v3po/interfaces/ProxyArpCustomizerTest.java | 97 ------ .../v3po/interfaces/RewriteCustomizerTest.java | 198 ------------ .../v3po/interfaces/RoutingCustomizerTest.java | 97 ------ .../interfaces/SubInterfaceCustomizerTest.java | 258 ---------------- .../interfaces/SubInterfaceL2CustomizerTest.java | 109 ------- .../v3po/interfaces/TapCustomizerTest.java | 129 -------- .../v3po/interfaces/VhostUserCustomizerTest.java | 205 ------------- .../v3po/interfaces/VxlanCustomizerTest.java | 227 -------------- .../v3po/interfaces/VxlanGpeCustomizerTest.java | 218 ------------- .../v3po/interfaces/acl/AclWriterTest.java | 103 ------- .../interfaces/acl/common/AceEthWriterTest.java | 94 ------ .../interfaces/acl/common/AceIp4WriterTest.java | 189 ------------ .../interfaces/acl/common/AceIp6WriterTest.java | 201 ------------ .../acl/common/AceIpAndEthWriterTest.java | 123 -------- .../acl/common/AceIpWriterTestUtils.java | 34 --- .../acl/common/AclTableContextManagerImplTest.java | 62 ---- .../v3po/interfaces/acl/common/PortPairTest.java | 114 ------- .../acl/egress/EgressIetfAclWriterTest.java | 151 --------- .../acl/egress/IetfAclCustomizerTest.java | 114 ------- .../egress/SubInterfaceIetfAclCustomizerTest.java | 130 -------- .../acl/ingress/IetfAclCustomizerTest.java | 205 ------------- .../acl/ingress/SubInterfaceAclCustomizerTest.java | 140 --------- .../ingress/SubInterfaceIetfAclCustomizerTest.java | 154 ---------- .../interfaces/ip/Ipv4AddressCustomizerTest.java | 338 --------------------- .../interfaces/ip/Ipv4NeighbourCustomizerTest.java | 120 -------- .../ip/SubInterfaceIpv4AddressCustomizerTest.java | 144 --------- .../ip/subnet/validation/SubnetValidatorTest.java | 88 ------ .../interfaces/pbb/PbbRewriteCustomizerTest.java | 312 ------------------- .../interfacesstate/EthernetCustomizerTest.java | 90 ------ .../v3po/interfacesstate/GreCustomizerTest.java | 131 -------- .../interfacesstate/InterfaceCustomizerTest.java | 201 ------------ .../InterfaceDataTranslatorTest.java | 55 ---- .../v3po/interfacesstate/L2CustomizerTest.java | 145 --------- .../interfacesstate/RewriteCustomizerTest.java | 114 ------- .../SubInterfaceCustomizerTest.java | 129 -------- .../SubInterfaceL2CustomizerTest.java | 80 ----- .../v3po/interfacesstate/TapCustomizerTest.java | 98 ------ .../interfacesstate/VhostUserCustomizerTest.java | 115 ------- .../v3po/interfacesstate/VxlanCustomizerTest.java | 133 -------- .../interfacesstate/VxlanGpeCustomizerTest.java | 278 ----------------- .../acl/ingress/AclCustomizerTest.java | 99 ------ .../acl/ingress/SubInterfaceAclCustomizerTest.java | 108 ------- .../ip/Ipv4AddressCustomizerTest.java | 284 ----------------- .../interfacesstate/ip/Ipv4CustomizerTest.java | 44 --- .../ip/SubInterfaceIpv4AddressCustomizerTest.java | 247 --------------- .../pbb/PbbRewriteStateCustomizerTest.java | 35 --- .../InterfaceChangeNotificationProducerTest.java | 112 ------- .../ArpTerminationTableEntryCustomizerTest.java | 171 ----------- .../v3po/vpp/BridgeDomainCustomizerTest.java | 276 ----------------- .../v3po/vpp/L2FibEntryCustomizerTest.java | 190 ------------ .../vppclassifier/ClassifySessionReaderTest.java | 116 ------- .../vppclassifier/ClassifySessionWriterTest.java | 179 ----------- .../vppclassifier/ClassifyTableReaderTest.java | 126 -------- .../vppclassifier/ClassifyTableWriterTest.java | 181 ----------- .../VppClassifierContextManagerImplTest.java | 163 ---------- .../v3po/vppstate/BridgeDomainCustomizerTest.java | 47 --- .../v3po/vppstate/L2FibEntryCustomizerTest.java | 124 -------- .../v3po/vppstate/VersionCustomizerTest.java | 60 ---- .../translate/v3po/vppstate/VppStateTest.java | 326 -------------------- .../translate/vpp/util/SubinterfaceUtilsTest.java | 32 -- 345 files changed, 21990 insertions(+), 21996 deletions(-) create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/AclWriterFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/DisabledInterfacesManager.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/EgressIetfAClWriterProvider.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/IngressIetfAClWriterProvider.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/InterfacesStateReaderFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/InterfacesWriterFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/SubinterfaceAugmentationWriterFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/SubinterfaceStateAugmentationReaderFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppClassifierHoneycombWriterFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppClassifierReaderFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppHoneycombWriterFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppStateHoneycombReaderFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/EthernetCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterconnectionWriteUtils.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/L2Customizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/LoopbackCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RoutingCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2Customizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/TapCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/IetfAclWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AbstractIetfAclWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4Writer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6Writer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManager.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImpl.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTranslator.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/IetfAclWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip4AclTranslator.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip6AclTranslator.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/L2AclTranslator.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPair.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Customizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Writer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv6Customizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidationException.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidator.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/notification/InterfaceChangeNotificationProducer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/util/SubInterfaceUtils.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReader.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReader.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManager.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImpl.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeReader.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeWriter.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/AclWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/DisabledInterfacesManager.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/EgressIetfAClWriterProvider.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/IngressIetfAClWriterProvider.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesStateReaderFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/SubinterfaceAugmentationWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/SubinterfaceStateAugmentationReaderFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/V3poModule.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppClassifierHoneycombWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppClassifierReaderFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppHoneycombWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppStateHoneycombReaderFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/cfgattrs/V3poConfiguration.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/EthernetCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/GreCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/InterconnectionWriteUtils.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/L2Customizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/LoopbackCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/RewriteCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2Customizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/TapCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VhostUserCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanGpeCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/IetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AbstractIetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceEthWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp4Writer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp6Writer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpAndEthWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManager.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImpl.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTranslator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/IetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/Ip4AclTranslator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/Ip6AclTranslator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/L2AclTranslator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/PortPair.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Customizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Writer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv6Customizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidationException.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/EthernetCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/GreCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterconnectionReadUtils.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslator.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/L2Customizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ProxyArpCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/RewriteCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/TapCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VhostUserCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanGpeCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclReader.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Customizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Reader.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv6Customizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/notification/InterfaceChangeNotificationProducer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/ArpTerminationTableEntryCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/BridgeDomainCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/L2FibEntryCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionReader.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableReader.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManager.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManagerImpl.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppNodeReader.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppNodeWriter.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/BridgeDomainCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/L2FibEntryCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/VersionCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/vpp/util/SubInterfaceUtils.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/DisabledInterfacesManagerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/V3poModuleTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AclCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceTypeTestUtils.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/L2CustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/LoopbackCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/RoutingCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2CustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/TapCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/AclWriterTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriterTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4WriterTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6WriterTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpWriterTestUtils.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPairTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidatorTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslatorTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/L2CustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2CustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4CustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/notification/InterfaceChangeNotificationProducerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/util/SubinterfaceUtilsTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReaderTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriterTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReaderTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriterTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImplTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/VppStateTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/DisabledInterfacesManagerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/V3poModuleTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/AclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/GreCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceTypeTestUtils.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/L2CustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/LoopbackCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RewriteCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2CustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/TapCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VhostUserCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanGpeCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AclWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceEthWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp4WriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp6WriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpWriterTestUtils.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/PortPairTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidatorTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/EthernetCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/GreCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslatorTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/L2CustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/RewriteCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceL2CustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/TapCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VhostUserCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4CustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/notification/InterfaceChangeNotificationProducerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/ArpTerminationTableEntryCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/BridgeDomainCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/L2FibEntryCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionReaderTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableReaderTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableWriterTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManagerImplTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/BridgeDomainCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/L2FibEntryCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/VersionCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/VppStateTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/vpp/util/SubinterfaceUtilsTest.java (limited to 'v3po') diff --git a/v3po/api/pom.xml b/v3po/api/pom.xml index b625f79df..4b34c0d7f 100644 --- a/v3po/api/pom.xml +++ b/v3po/api/pom.xml @@ -18,11 +18,10 @@ io.fd.honeycomb.common api-parent 1.16.12-SNAPSHOT - ../../common/api-parent 4.0.0 - io.fd.honeycomb.v3po + io.fd.hc2vpp.v3po v3po-api ${project.artifactId} 1.16.12-SNAPSHOT @@ -50,7 +49,7 @@ yang-ext - io.fd.honeycomb.vpp + io.fd.hc2vpp.common naming-context-api ${project.version} diff --git a/v3po/pom.xml b/v3po/pom.xml index 83df160ad..28e9ab023 100644 --- a/v3po/pom.xml +++ b/v3po/pom.xml @@ -19,10 +19,9 @@ io.fd.honeycomb.common honeycomb-parent 1.16.12-SNAPSHOT - ../common/honeycomb-parent - io.fd.honeycomb.v3po + io.fd.hc2vpp.v3po v3po-aggregator 1.16.12-SNAPSHOT ${project.artifactId} diff --git a/v3po/v3po2vpp/pom.xml b/v3po/v3po2vpp/pom.xml index 79f1d6650..d4c65debb 100644 --- a/v3po/v3po2vpp/pom.xml +++ b/v3po/v3po2vpp/pom.xml @@ -17,14 +17,14 @@ - io.fd.honeycomb.vpp + io.fd.hc2vpp.common vpp-impl-parent 1.16.12-SNAPSHOT ../../vpp-common/vpp-impl-parent 4.0.0 - io.fd.honeycomb.v3po + io.fd.hc2vpp.v3po v3po2vpp ${project.artifactId} 1.16.12-SNAPSHOT @@ -47,7 +47,7 @@ ${project.version} - io.fd.honeycomb.vpp + io.fd.hc2vpp.common vpp-translate-utils ${project.version} @@ -88,7 +88,7 @@ - io.fd.honeycomb.vpp + io.fd.hc2vpp.common vpp-translate-test ${project.version} test diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/AclWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/AclWriterFactory.java new file mode 100644 index 000000000..dbac5f342 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/AclWriterFactory.java @@ -0,0 +1,58 @@ +/* + * 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; + +import static io.fd.hc2vpp.v3po.InterfacesWriterFactory.IETF_ACL_ID; +import static io.fd.hc2vpp.v3po.SubinterfaceAugmentationWriterFactory.SUBIF_IETF_ACL_ID; + +import com.google.common.collect.Sets; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.hc2vpp.v3po.interfaces.acl.IetfAclWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntries; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Actions; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Matches; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class AclWriterFactory implements WriterFactory { + + public static final InstanceIdentifier ACL_ID = + InstanceIdentifier.create(AccessLists.class).child(Acl.class); + + @Override + public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { + + final InstanceIdentifier aclIdRelative = InstanceIdentifier.create(Acl.class); + + final InstanceIdentifier aceId = aclIdRelative.child(AccessListEntries.class).child(Ace.class); + final InstanceIdentifier actionsId = aceId.child(Actions.class); + final InstanceIdentifier matchesId = aceId.child(Matches.class); + final InstanceIdentifier srcPortId = matchesId.child((Class)SourcePortRange.class); + final InstanceIdentifier dstPortId = matchesId.child((Class)DestinationPortRange.class); + + registry.subtreeAddBefore(Sets.newHashSet(aceId, actionsId, matchesId, srcPortId, dstPortId), + new GenericListWriter<>(ACL_ID, new IetfAclWriter()), + Sets.newHashSet(IETF_ACL_ID, SUBIF_IETF_ACL_ID)); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/DisabledInterfacesManager.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/DisabledInterfacesManager.java new file mode 100644 index 000000000..97bab706d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/DisabledInterfacesManager.java @@ -0,0 +1,106 @@ +/* + * 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; + +import com.google.common.base.Optional; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.util.read.BindingBrokerReader; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.DisabledInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.DisabledInterfacesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndex; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndexBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndexKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +/** + * Facade on top of {@link MappingContext} making access to {@link DisabledInterfaces} easier. + */ +public class DisabledInterfacesManager { + + private static final InstanceIdentifier + DISABLED_IFCS_ROOT = InstanceIdentifier.create(DisabledInterfaces.class); + + /** + * Read the list of currently disabled interfaces. + */ + public List getDisabledInterfaces(@Nonnull final MappingContext ctx) { + final Optional read = ctx.read(DISABLED_IFCS_ROOT); + if (read.isPresent()) { + return read.get().getDisabledInterfaceIndex().stream() + .map(DisabledInterfaceIndex::getIndex) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + /** + * Check whether a specific interface is disabled. + */ + public boolean isInterfaceDisabled(final int index, @Nonnull final MappingContext ctx) { + return ctx.read(getKeyedId(index)) + .isPresent(); + } + + /** + * Make a specific interface disabled. + */ + public void disableInterface(final int index, @Nonnull final MappingContext ctx) { + ctx.put(getKeyedId(index), getDisabledInterfaceIndex(index)); + } + + /** + * Remove interface disability. + */ + public void removeDisabledInterface(final int index, @Nonnull final MappingContext ctx) { + ctx.delete(getKeyedId(index)); + } + + private static DisabledInterfaceIndex getDisabledInterfaceIndex(final int index) { + return new DisabledInterfaceIndexBuilder().setIndex(index).build(); + } + + private static KeyedInstanceIdentifier getKeyedId(final int id) { + return DISABLED_IFCS_ROOT.child(DisabledInterfaceIndex.class, new DisabledInterfaceIndexKey(id)); + } + + public static final class ContextsReaderFactory implements ReaderFactory { + + @Inject + @Named("honeycomb-context") + private DataBroker contextBindingBrokerDependency; + + @Override + public void init(final ModifiableReaderRegistryBuilder registry) { + registry.add(new BindingBrokerReader<>(DISABLED_IFCS_ROOT, + contextBindingBrokerDependency, + LogicalDatastoreType.OPERATIONAL, DisabledInterfacesBuilder.class)); + } + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/EgressIetfAClWriterProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/EgressIetfAClWriterProvider.java new file mode 100644 index 000000000..0e4aaa80d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/EgressIetfAClWriterProvider.java @@ -0,0 +1,39 @@ +/* + * 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; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import io.fd.hc2vpp.v3po.interfaces.acl.egress.EgressIetfAclWriter; +import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManagerImpl; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; + +class EgressIetfAClWriterProvider implements Provider { + + private final FutureJVppCore jvpp; + + @Inject + public EgressIetfAClWriterProvider(final FutureJVppCore jvpp) { + this.jvpp = jvpp; + } + + @Override + public EgressIetfAclWriter get() { + return new EgressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Egress)); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/IngressIetfAClWriterProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/IngressIetfAClWriterProvider.java new file mode 100644 index 000000000..12349a356 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/IngressIetfAClWriterProvider.java @@ -0,0 +1,39 @@ +/* + * 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; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManagerImpl; +import io.fd.hc2vpp.v3po.interfaces.acl.ingress.IngressIetfAclWriter; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; + +class IngressIetfAClWriterProvider implements Provider { + + private final FutureJVppCore jvpp; + + @Inject + public IngressIetfAClWriterProvider(final FutureJVppCore jvpp) { + this.jvpp = jvpp; + } + + @Override + public IngressIetfAclWriter get() { + return new IngressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Ingress)); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/InterfacesStateReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/InterfacesStateReaderFactory.java new file mode 100644 index 000000000..f01cd9e99 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/InterfacesStateReaderFactory.java @@ -0,0 +1,187 @@ +/* + * 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; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.v3po.interfacesstate.ip.Ipv4AddressCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericInitListReader; +import io.fd.honeycomb.translate.impl.read.GenericInitReader; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.impl.read.GenericReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.hc2vpp.v3po.interfacesstate.EthernetCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.GreCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.L2Customizer; +import io.fd.hc2vpp.v3po.interfacesstate.ProxyArpCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.TapCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.VhostUserCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.VxlanCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.VxlanGpeCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.acl.ingress.AclCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.ip.Ipv4Customizer; +import io.fd.hc2vpp.v3po.interfacesstate.ip.Ipv4NeighbourCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.ip.Ipv6Customizer; +import io.fd.hc2vpp.v3po.interfacesstate.pbb.PbbRewriteStateCustomizer; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Ethernet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Gre; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Tap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUser; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Vxlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpe; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteStateInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteStateInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteState; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class InterfacesStateReaderFactory implements ReaderFactory { + + private final NamingContext ifcNamingCtx; + private final NamingContext bdNamingCtx; + private final VppClassifierContextManager classifyContext; + private final DisabledInterfacesManager ifcDisableContext; + private final FutureJVppCore jvpp; + + static final InstanceIdentifier IFC_STATE_ID = + InstanceIdentifier.create(InterfacesState.class); + static final InstanceIdentifier IFC_ID = IFC_STATE_ID.child(Interface.class); + + @Inject + public InterfacesStateReaderFactory(final FutureJVppCore jvpp, + @Named("interface-context") final NamingContext ifcNamingCtx, + @Named("bridge-domain-context") final NamingContext bdNamingCtx, + @Named("classify-table-context") final VppClassifierContextManager classifyContext, + final DisabledInterfacesManager ifcDisableContext) { + this.jvpp = jvpp; + this.ifcNamingCtx = ifcNamingCtx; + this.bdNamingCtx = bdNamingCtx; + this.classifyContext = classifyContext; + this.ifcDisableContext = ifcDisableContext; + } + + @Override + public void init(final ModifiableReaderRegistryBuilder registry) { + // InterfacesState(Structural) + registry.addStructuralReader(IFC_STATE_ID, InterfacesStateBuilder.class); + // Interface + registry.add(new GenericInitListReader<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcNamingCtx, ifcDisableContext))); + + // v3po.yang + initVppIfcAugmentationReaders(registry, IFC_ID); + // ietf-ip.yang + 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, + final InstanceIdentifier ifcId) { + // Interface2Augmentation(Structural) + final InstanceIdentifier ifc2AugId = ifcId.augmentation(Interface2.class); + registry.addStructuralReader(ifc2AugId, Interface2Builder.class); + // Ipv4 + final InstanceIdentifier ipv4Id = ifc2AugId.child(Ipv4.class); + registry.add(new GenericReader<>(ipv4Id, new Ipv4Customizer(jvpp))); + // Address + final InstanceIdentifier
ipv4AddrId = ipv4Id.child(Address.class); + registry.add(new GenericInitListReader<>(ipv4AddrId, new Ipv4AddressCustomizer(jvpp, ifcNamingCtx))); + // Neighbor + final InstanceIdentifier neighborId = ipv4Id.child(Neighbor.class); + registry.add(new GenericListReader<>(neighborId, new Ipv4NeighbourCustomizer(jvpp))); + // Ipv6 + final InstanceIdentifier ipv6Id = ifc2AugId.child(Ipv6.class); + registry.add(new GenericReader<>(ipv6Id, new Ipv6Customizer(jvpp, ifcNamingCtx))); + } + + private void initVppIfcAugmentationReaders(final ModifiableReaderRegistryBuilder registry, + final InstanceIdentifier ifcId) { + // VppInterfaceStateAugmentation + final InstanceIdentifier vppIfcAugId = + ifcId.augmentation(VppInterfaceStateAugmentation.class); + registry.addStructuralReader(vppIfcAugId, VppInterfaceStateAugmentationBuilder.class); + // Ethernet + registry.add(new GenericInitReader<>(vppIfcAugId.child(Ethernet.class), + new EthernetCustomizer(jvpp, ifcNamingCtx))); + // Tap + registry.add(new GenericInitReader<>(vppIfcAugId.child(Tap.class), new TapCustomizer(jvpp, ifcNamingCtx))); + // VhostUser + registry.add(new GenericInitReader<>(vppIfcAugId.child(VhostUser.class), + new VhostUserCustomizer(jvpp, ifcNamingCtx))); + // Vxlan + registry.add(new GenericInitReader<>(vppIfcAugId.child(Vxlan.class), new VxlanCustomizer(jvpp, ifcNamingCtx))); + // VxlanGpe + registry.add(new GenericInitReader<>(vppIfcAugId.child(VxlanGpe.class), + new VxlanGpeCustomizer(jvpp, ifcNamingCtx))); + // Gre + registry.add(new GenericInitReader<>(vppIfcAugId.child(Gre.class), new GreCustomizer(jvpp, ifcNamingCtx))); + // L2 + registry.add(new GenericInitReader<>(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 GenericInitReader<>(aclIid.child(Ingress.class), + new AclCustomizer(jvpp, ifcNamingCtx, classifyContext))); + + // Proxy ARP + registry.add(new GenericReader<>(vppIfcAugId.child(ProxyArp.class), new ProxyArpCustomizer(jvpp, + 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/hc2vpp/v3po/InterfacesWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/InterfacesWriterFactory.java new file mode 100644 index 000000000..eb68b6fbf --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/InterfacesWriterFactory.java @@ -0,0 +1,244 @@ +/* + * 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; + +import static io.fd.hc2vpp.v3po.VppClassifierHoneycombWriterFactory.CLASSIFY_SESSION_ID; +import static io.fd.hc2vpp.v3po.VppClassifierHoneycombWriterFactory.CLASSIFY_TABLE_ID; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.v3po.interfaces.EthernetCustomizer; +import io.fd.hc2vpp.v3po.interfaces.GreCustomizer; +import io.fd.hc2vpp.v3po.interfaces.L2Customizer; +import io.fd.hc2vpp.v3po.interfaces.LoopbackCustomizer; +import io.fd.hc2vpp.v3po.interfaces.TapCustomizer; +import io.fd.hc2vpp.v3po.interfaces.VxlanCustomizer; +import io.fd.hc2vpp.v3po.interfaces.VxlanGpeCustomizer; +import io.fd.hc2vpp.v3po.interfaces.acl.egress.EgressIetfAclWriter; +import io.fd.hc2vpp.v3po.interfaces.acl.ingress.AclCustomizer; +import io.fd.hc2vpp.v3po.interfaces.ip.Ipv4NeighbourCustomizer; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.impl.write.GenericWriter; +import io.fd.hc2vpp.v3po.interfaces.InterfaceCustomizer; +import io.fd.hc2vpp.v3po.interfaces.ProxyArpCustomizer; +import io.fd.hc2vpp.v3po.interfaces.RoutingCustomizer; +import io.fd.hc2vpp.v3po.interfaces.VhostUserCustomizer; +import io.fd.hc2vpp.v3po.interfaces.acl.ingress.IngressIetfAclWriter; +import io.fd.hc2vpp.v3po.interfaces.ip.Ipv4AddressCustomizer; +import io.fd.hc2vpp.v3po.interfaces.ip.Ipv4Customizer; +import io.fd.hc2vpp.v3po.interfaces.ip.Ipv6Customizer; +import io.fd.hc2vpp.v3po.interfaces.pbb.PbbRewriteCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Set; +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.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Ethernet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Loopback; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Routing; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.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); + public static final InstanceIdentifier VPP_IFC_AUG_ID = + 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.rev161214.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.rev161214.interfaces._interface.ietf.acl.Egress.class); + + private final FutureJVppCore jvpp; + private final IngressIetfAclWriter ingressAclWriter; + private final EgressIetfAclWriter egressAclWriter; + private final NamingContext bdNamingContext; + private final NamingContext ifcNamingContext; + private final VppClassifierContextManager classifyTableContext; + private final DisabledInterfacesManager ifcDisableContext; + + @Inject + public InterfacesWriterFactory(final FutureJVppCore vppJvppIfcDependency, + final IngressIetfAclWriter ingressAclWriter, + final EgressIetfAclWriter egressAclWriter, + @Named("bridge-domain-context") final NamingContext bridgeDomainContextDependency, + @Named("interface-context") final NamingContext interfaceContextDependency, + @Named("classify-table-context") final VppClassifierContextManager classifyTableContext, + final DisabledInterfacesManager ifcDisableContext) { + this.jvpp = vppJvppIfcDependency; + this.ingressAclWriter = ingressAclWriter; + this.egressAclWriter = egressAclWriter; + this.bdNamingContext = bridgeDomainContextDependency; + this.ifcNamingContext = interfaceContextDependency; + this.ifcDisableContext = ifcDisableContext; + this.classifyTableContext = classifyTableContext; + } + + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + // Interfaces + // Interface = + registry.add(new GenericListWriter<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcNamingContext))); + // VppInterfaceAugmentation + addVppInterfaceAgmentationWriters(IFC_ID, registry); + // Interface1 (ietf-ip augmentation) + addInterface1AugmentationWriters(IFC_ID, registry); + // SubinterfaceAugmentation + new SubinterfaceAugmentationWriterFactory(jvpp, ingressAclWriter, egressAclWriter, ifcNamingContext, bdNamingContext, + classifyTableContext).init(registry); + + addPbbAugmentationWriters(IFC_ID, registry); + } + + private void addInterface1AugmentationWriters(final InstanceIdentifier ifcId, + final ModifiableWriterRegistryBuilder registry) { + final InstanceIdentifier ifc1AugId = ifcId.augmentation(Interface1.class); + // Ipv6(after interface) = + registry.addAfter(new GenericWriter<>(ifc1AugId.child(Ipv6.class), new Ipv6Customizer(jvpp)), + ifcId); + // Ipv4(after interface) + final InstanceIdentifier ipv4Id = ifc1AugId.child(Ipv4.class); + registry.addAfter(new GenericWriter<>(ipv4Id, new Ipv4Customizer(jvpp)), + ifcId); + // Address(after Ipv4) = + final InstanceIdentifier
ipv4AddressId = ipv4Id.child(Address.class); + registry.addAfter(new GenericListWriter<>(ipv4AddressId, new Ipv4AddressCustomizer(jvpp, ifcNamingContext)), + ipv4Id); + // Neighbor(after ipv4Address) + registry.addAfter(new GenericListWriter<>(ipv4Id.child(Neighbor.class), new Ipv4NeighbourCustomizer(jvpp, + ifcNamingContext)), + ipv4AddressId); + } + + private void addVppInterfaceAgmentationWriters(final InstanceIdentifier ifcId, + final ModifiableWriterRegistryBuilder registry) { + // 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); + // 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); + // 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); + // 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); + // Loopback(Needs to be executed before Interface customizer) = + final InstanceIdentifier loopbackId = VPP_IFC_AUG_ID.child(Loopback.class); + registry.addBefore(new GenericWriter<>(loopbackId, new LoopbackCustomizer(jvpp, ifcNamingContext)), + 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); + + + final Set> specificIfcTypes = Sets.newHashSet(vhostId, vxlanGpeId, vxlanGpeId, tapId); + + // Ethernet = + 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); + // 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); + // Proxy Arp (execute after specific interface customizers) + registry.addAfter( + 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)); + + // 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.rev161214.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.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl.class); + registry.subtreeAdd( + Sets.newHashSet(accessListsIdIngress, aclIdIngress), + new GenericWriter<>(INGRESS_IETF_ACL_ID, new io.fd.hc2vpp.v3po.interfaces.acl.ingress.IetfAclCustomizer(ingressAclWriter, 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.rev161214.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.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl.class); + registry.subtreeAdd( + Sets.newHashSet(accessListsIdEgress, aclIdEgress), + new GenericWriter<>(EGRESS_IETF_ACL_ID, + new io.fd.hc2vpp.v3po.interfaces.acl.egress.IetfAclCustomizer(egressAclWriter, + 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/hc2vpp/v3po/SubinterfaceAugmentationWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/SubinterfaceAugmentationWriterFactory.java new file mode 100644 index 000000000..c8a7d281c --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/SubinterfaceAugmentationWriterFactory.java @@ -0,0 +1,158 @@ +/* + * 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; + +import static io.fd.hc2vpp.v3po.VppClassifierHoneycombWriterFactory.CLASSIFY_SESSION_ID; +import static io.fd.hc2vpp.v3po.VppClassifierHoneycombWriterFactory.CLASSIFY_TABLE_ID; + +import com.google.common.collect.Sets; +import io.fd.hc2vpp.v3po.interfaces.acl.egress.EgressIetfAclWriter; +import io.fd.hc2vpp.v3po.interfaces.acl.ingress.SubInterfaceAclCustomizer; +import io.fd.hc2vpp.v3po.interfaces.acl.ingress.SubInterfaceIetfAclCustomizer; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.impl.write.GenericWriter; +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.acl.ingress.IngressIetfAclWriter; +import io.fd.hc2vpp.v3po.interfaces.ip.SubInterfaceIpv4AddressCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +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.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTagged; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class SubinterfaceAugmentationWriterFactory implements WriterFactory { + + private final FutureJVppCore jvpp; + private final IngressIetfAclWriter ingressAclWriter; + private final EgressIetfAclWriter egressAclWriter; + private final NamingContext ifcContext; + private final NamingContext bdContext; + private final VppClassifierContextManager classifyTableContext; + + public static final InstanceIdentifier SUB_IFC_AUG_ID = + InterfacesWriterFactory.IFC_ID.augmentation(SubinterfaceAugmentation.class); + public static final InstanceIdentifier SUB_IFC_ID = + SUB_IFC_AUG_ID.child(SubInterfaces.class).child(SubInterface.class); + public static final InstanceIdentifier L2_ID = SUB_IFC_ID.child( + L2.class); + public static final InstanceIdentifier SUBIF_ACL_ID = SUB_IFC_ID.child(Acl.class); + public static final InstanceIdentifier SUBIF_INGRESS_ACL_ID = SUBIF_ACL_ID.child(Ingress.class); + public static final InstanceIdentifier SUBIF_IETF_ACL_ID = SUB_IFC_ID.child(IetfAcl.class); + public static final InstanceIdentifier SUBIF_INGRESS_IETF_ACL_ID = SUBIF_IETF_ACL_ID.child( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress.class); + public static final InstanceIdentifier SUBIF_EGRESS_IETF_ACL_ID = SUBIF_IETF_ACL_ID.child( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress.class); + + public SubinterfaceAugmentationWriterFactory(final FutureJVppCore jvpp, + final IngressIetfAclWriter ingressAclWriter, + final EgressIetfAclWriter egressAclWriter, + final NamingContext ifcContext, final NamingContext bdContext, final VppClassifierContextManager classifyTableContext) { + this.jvpp = jvpp; + this.ingressAclWriter = ingressAclWriter; + this.egressAclWriter = egressAclWriter; + this.ifcContext = ifcContext; + this.bdContext = bdContext; + this.classifyTableContext = classifyTableContext; + } + + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + // Subinterfaces + // Subinterface(Handle only after all interface related stuff gets processed) = + registry.subtreeAddAfter( + // TODO HONEYCOMB-188 this customizer covers quite a lot of complex child nodes (maybe refactor ?) + Sets.newHashSet( + InstanceIdentifier.create(SubInterface.class).child(Tags.class), + InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class), + InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class).child( + Dot1qTag.class), + InstanceIdentifier.create(SubInterface.class).child(Match.class), + InstanceIdentifier.create(SubInterface.class).child(Match.class).child(VlanTagged.class)), + new GenericListWriter<>(SUB_IFC_ID, new SubInterfaceCustomizer(jvpp, ifcContext)), + InterfacesWriterFactory.IFC_ID); + // L2 = + registry.addAfter(new GenericWriter<>(L2_ID, new SubInterfaceL2Customizer(jvpp, ifcContext, bdContext)), + SUB_IFC_ID); + // Rewrite(also handles pushTags + pushTags/dot1qtag) = + final InstanceIdentifier rewriteId = L2_ID.child(Rewrite.class); + registry.subtreeAddAfter( + Sets.newHashSet( + InstanceIdentifier.create(Rewrite.class).child(PushTags.class), + InstanceIdentifier.create(Rewrite.class).child(PushTags.class) + .child(org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), + new GenericWriter<>(rewriteId, new RewriteCustomizer(jvpp, ifcContext)), + L2_ID); + // Ipv4(handled after L2 and L2/rewrite is done) = + final InstanceIdentifier
ipv4SubifcAddressId = SUB_IFC_ID.child(Ipv4.class).child(Address.class); + registry.addAfter(new GenericListWriter<>(ipv4SubifcAddressId, + new SubInterfaceIpv4AddressCustomizer(jvpp, ifcContext)), + rewriteId); + + // Ingress (execute after classify table and session writers) + // also handles L2Acl, Ip4Acl and Ip6Acl: + final InstanceIdentifier aclId = InstanceIdentifier.create(Ingress.class); + registry + .subtreeAddAfter( + Sets.newHashSet(aclId.child(L2Acl.class), aclId.child(Ip4Acl.class), aclId.child(Ip6Acl.class)), + new GenericWriter<>(SUBIF_INGRESS_ACL_ID, new SubInterfaceAclCustomizer(jvpp, ifcContext, 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.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress.class) + .child(AccessLists.class); + final InstanceIdentifier aclIdIngress = accessListsIdIngress.child( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl.class); + registry.subtreeAdd( + Sets.newHashSet(accessListsIdIngress, aclIdIngress), + new GenericWriter<>(SUBIF_INGRESS_IETF_ACL_ID, new SubInterfaceIetfAclCustomizer(ingressAclWriter, ifcContext))); + + // Egress IETF-ACL, also handles AccessLists and Acl: + final InstanceIdentifier accessListsIdEgress = InstanceIdentifier.create( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress.class) + .child(AccessLists.class); + final InstanceIdentifier aclIdEgress = accessListsIdEgress.child( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl.class); + registry.subtreeAdd( + Sets.newHashSet(accessListsIdEgress, aclIdEgress), + new GenericWriter<>(SUBIF_EGRESS_IETF_ACL_ID, new io.fd.hc2vpp.v3po.interfaces.acl.egress.SubInterfaceIetfAclCustomizer( + egressAclWriter, ifcContext))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/SubinterfaceStateAugmentationReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/SubinterfaceStateAugmentationReaderFactory.java new file mode 100644 index 000000000..ec4c50659 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/SubinterfaceStateAugmentationReaderFactory.java @@ -0,0 +1,118 @@ +/* + * 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; + +import com.google.common.collect.Sets; +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.acl.ingress.SubInterfaceAclCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.ip.SubInterfaceIpv4AddressCustomizer; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.impl.read.GenericInitListReader; +import io.fd.honeycomb.translate.impl.read.GenericInitReader; +import io.fd.honeycomb.translate.impl.read.GenericReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.hc2vpp.common.translate.util.NamingContext; +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.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfacesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTagged; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +final class SubinterfaceStateAugmentationReaderFactory implements ReaderFactory { + + private final FutureJVppCore jvpp; + private final NamingContext ifcCtx; + private final NamingContext bdCtx; + private final VppClassifierContextManager classifyCtx; + + SubinterfaceStateAugmentationReaderFactory(final FutureJVppCore jvpp, final NamingContext ifcCtx, + final NamingContext bdCtx, + final VppClassifierContextManager classifyCtx) { + this.jvpp = jvpp; + this.ifcCtx = ifcCtx; + this.bdCtx = bdCtx; + this.classifyCtx = classifyCtx; + } + + @Override + public void init(final ModifiableReaderRegistryBuilder registry) { + // SubinterfaceStateAugmentation(Structural) + final InstanceIdentifier subIfcAugId = + InterfacesStateReaderFactory.IFC_ID.augmentation(SubinterfaceStateAugmentation.class); + registry.addStructuralReader(subIfcAugId, SubinterfaceStateAugmentationBuilder.class); + // SubInterfaces(Structural) + final InstanceIdentifier subIfcsId = subIfcAugId.child(SubInterfaces.class); + registry.addStructuralReader(subIfcsId, SubInterfacesBuilder.class); + // SubInterface(Subtree) + final InstanceIdentifier subIfcId = subIfcsId.child(SubInterface.class); + registry.subtreeAdd(Sets.newHashSet( + InstanceIdentifier.create(SubInterface.class).child(Tags.class), + InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class), + InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class).child(Dot1qTag.class), + InstanceIdentifier.create(SubInterface.class).child(Match.class), + InstanceIdentifier.create(SubInterface.class).child(Match.class).child(VlanTagged.class)), + new GenericInitListReader<>(subIfcId, new SubInterfaceCustomizer(jvpp, ifcCtx))); + // L2 + final InstanceIdentifier l2Id = subIfcId.child(L2.class); + registry.add(new GenericInitReader<>(l2Id, new SubInterfaceL2Customizer(jvpp, ifcCtx, bdCtx))); + // Rewrite(Subtree) + registry.subtreeAdd(Sets.newHashSet( + InstanceIdentifier.create(Rewrite.class).child(PushTags.class), + InstanceIdentifier.create(Rewrite.class).child(PushTags.class) + .child( + org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), + new GenericReader<>(l2Id.child(Rewrite.class), new RewriteCustomizer(jvpp, ifcCtx))); + // Ipv4(Structural) + final InstanceIdentifier ipv4Id = subIfcId.child(Ipv4.class); + registry.addStructuralReader(ipv4Id, Ipv4Builder.class); + // Address + registry.add( + new GenericInitListReader<>(ipv4Id.child(Address.class), new SubInterfaceIpv4AddressCustomizer(jvpp, ifcCtx))); + // Acl(Structural) + final InstanceIdentifier aclIid = subIfcId.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 GenericInitReader<>(aclIid.child(Ingress.class), + new SubInterfaceAclCustomizer(jvpp, ifcCtx, classifyCtx))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java new file mode 100644 index 000000000..ad9d04888 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java @@ -0,0 +1,92 @@ +/* + * 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; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import com.google.inject.name.Names; +import io.fd.hc2vpp.v3po.interfaces.acl.egress.EgressIetfAclWriter; +import io.fd.hc2vpp.v3po.notification.InterfaceChangeNotificationProducer; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManagerImpl; +import io.fd.honeycomb.notification.ManagedNotificationProducer; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.hc2vpp.v3po.cfgattrs.V3poConfiguration; +import io.fd.hc2vpp.v3po.interfaces.acl.ingress.IngressIetfAclWriter; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriterFactory; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import net.jmob.guice.conf.core.ConfigurationModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class V3poModule extends AbstractModule { + + private static final Logger LOG = LoggerFactory.getLogger(V3poModule.class); + + @Override + protected void configure() { + LOG.debug("Installing V3PO module"); + install(ConfigurationModule.create()); + requestInjection(V3poConfiguration.class); + + // TODO HONEYCOMB-173 put into constants + // Naming contexts + bind(NamingContext.class) + .annotatedWith(Names.named("interface-context")) + .toInstance(new NamingContext("interface-", "interface-context")); + bind(NamingContext.class) + .annotatedWith(Names.named("bridge-domain-context")) + .toInstance(new NamingContext("bridge-domain-", "bridge-domain-context")); + bind(VppClassifierContextManager.class) + .annotatedWith(Names.named("classify-table-context")) + .toInstance(new VppClassifierContextManagerImpl("classify-table-")); + + // Executor needed for keepalives + bind(ScheduledExecutorService.class).toInstance(Executors.newScheduledThreadPool(1)); + + // Utils + bind(IngressIetfAclWriter.class).toProvider(IngressIetfAClWriterProvider.class); + bind(EgressIetfAclWriter.class).toProvider(EgressIetfAClWriterProvider.class); + // Context utility for deleted interfaces + bind(DisabledInterfacesManager.class).toInstance(new DisabledInterfacesManager()); + + // Readers + final Multibinder readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + readerFactoryBinder.addBinding().to(InterfacesStateReaderFactory.class); + readerFactoryBinder.addBinding().to(VppStateHoneycombReaderFactory.class); + readerFactoryBinder.addBinding().to(VppClassifierReaderFactory.class); + // Expose disabled interfaces in operational data + readerFactoryBinder.addBinding().to(DisabledInterfacesManager.ContextsReaderFactory.class); + // Expose vpp-classfier-context interfaces in operational data + readerFactoryBinder.addBinding().to(VppClassifierContextManagerImpl.ContextsReaderFactory.class); + + // Writers + final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + writerFactoryBinder.addBinding().to(InterfacesWriterFactory.class); + writerFactoryBinder.addBinding().to(VppHoneycombWriterFactory.class); + writerFactoryBinder.addBinding().to(VppClassifierHoneycombWriterFactory.class); + writerFactoryBinder.addBinding().to(AclWriterFactory.class); + + // Notifications + final Multibinder notifiersBinder = + Multibinder.newSetBinder(binder(), ManagedNotificationProducer.class); + notifiersBinder.addBinding().to(InterfaceChangeNotificationProducer.class); + LOG.info("Module V3PO successfully configured"); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppClassifierHoneycombWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppClassifierHoneycombWriterFactory.java new file mode 100644 index 000000000..1443c5576 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppClassifierHoneycombWriterFactory.java @@ -0,0 +1,64 @@ +/* + * 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; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.v3po.vppclassifier.ClassifySessionWriter; +import io.fd.hc2vpp.v3po.vppclassifier.ClassifyTableWriter; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +public final class VppClassifierHoneycombWriterFactory implements WriterFactory { + + public static final InstanceIdentifier CLASSIFY_TABLE_ID = + InstanceIdentifier.create(VppClassifier.class).child(ClassifyTable.class); + + public static final InstanceIdentifier CLASSIFY_SESSION_ID = + CLASSIFY_TABLE_ID.child(ClassifySession.class); + + private final FutureJVppCore jvpp; + private final VppClassifierContextManager classifyTableContext; + + @Inject + public VppClassifierHoneycombWriterFactory(@Nonnull final FutureJVppCore jvpp, + @Named("classify-table-context") @Nonnull final VppClassifierContextManager classifyTableContext) { + this.jvpp = jvpp; + this.classifyTableContext = classifyTableContext; + } + + @Override + public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { + // Ordering here is: First create table, then create sessions and then assign as ACL + // ClassifyTable + registry.addBefore( + new GenericListWriter<>(CLASSIFY_TABLE_ID, new ClassifyTableWriter(jvpp, classifyTableContext)), + CLASSIFY_SESSION_ID); + // ClassifyTableSession + registry.addBefore( + new GenericListWriter<>(CLASSIFY_SESSION_ID, new ClassifySessionWriter(jvpp, classifyTableContext)), + InterfacesWriterFactory.ACL_ID); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppClassifierReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppClassifierReaderFactory.java new file mode 100644 index 000000000..d612314e1 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppClassifierReaderFactory.java @@ -0,0 +1,60 @@ +/* + * 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; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.translate.impl.read.GenericInitListReader; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.hc2vpp.v3po.vppclassifier.ClassifySessionReader; +import io.fd.hc2vpp.v3po.vppclassifier.ClassifyTableReader; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +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.classifier.rev161214.VppClassifierState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class VppClassifierReaderFactory implements ReaderFactory { + + private final FutureJVppCore jvpp; + private final VppClassifierContextManager classifyCtx; + + @Inject + public VppClassifierReaderFactory(final FutureJVppCore jvpp, + @Named("classify-table-context") final VppClassifierContextManager classifyCtx) { + this.jvpp = jvpp; + this.classifyCtx = classifyCtx; + } + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + // VppClassifierState + final InstanceIdentifier vppStateId = InstanceIdentifier.create(VppClassifierState.class); + registry.addStructuralReader(vppStateId, VppClassifierStateBuilder.class); + // ClassifyTable + final InstanceIdentifier classTblId = vppStateId.child(ClassifyTable.class); + registry.add(new GenericInitListReader<>(classTblId, new ClassifyTableReader(jvpp, classifyCtx))); + // ClassifySession + final InstanceIdentifier classSesId = classTblId.child(ClassifySession.class); + registry.add(new GenericListReader<>(classSesId, new ClassifySessionReader(jvpp, classifyCtx))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppHoneycombWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppHoneycombWriterFactory.java new file mode 100644 index 000000000..0f836d632 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppHoneycombWriterFactory.java @@ -0,0 +1,81 @@ +/* + * 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; + +import static io.fd.hc2vpp.v3po.InterfacesWriterFactory.L2_ID; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.v3po.vpp.ArpTerminationTableEntryCustomizer; +import io.fd.hc2vpp.v3po.vpp.BridgeDomainCustomizer; +import io.fd.hc2vpp.v3po.vpp.L2FibEntryCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Vpp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.ArpTerminationTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +public final class VppHoneycombWriterFactory implements WriterFactory { + + private final FutureJVppCore jvpp; + private final NamingContext bdContext; + private final NamingContext ifcContext; + + @Inject + public VppHoneycombWriterFactory(final FutureJVppCore vppJvppWriterDependency, + @Named("bridge-domain-context") final NamingContext bridgeDomainContextVppDependency, + @Named("interface-context") final NamingContext interfaceContextVppDependency) { + this.jvpp = vppJvppWriterDependency; + this.bdContext = bridgeDomainContextVppDependency; + this.ifcContext = interfaceContextVppDependency; + } + + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + // Vpp has no handlers + // BridgeDomains has no handlers + // BridgeDomain = + final InstanceIdentifier bdId = + InstanceIdentifier.create(Vpp.class).child(BridgeDomains.class).child(BridgeDomain.class); + registry.add(new GenericListWriter<>(bdId, new BridgeDomainCustomizer(jvpp, bdContext))); + // L2FibTable has no handlers + // L2FibEntry(handled after BridgeDomain and L2 of ifc and subifc) = + final InstanceIdentifier l2FibEntryId = bdId.child(L2FibTable.class).child(L2FibEntry.class); + registry.addAfter( + new GenericListWriter<>(l2FibEntryId, new L2FibEntryCustomizer(jvpp, bdContext, ifcContext)), + Sets.newHashSet( + bdId, + L2_ID, + SubinterfaceAugmentationWriterFactory.L2_ID)); + // ArpTerminationTable has no handlers + // ArpTerminationTableEntry(handled after BridgeDomain) = + final InstanceIdentifier arpEntryId = + bdId.child(ArpTerminationTable.class).child(ArpTerminationTableEntry.class); + registry.addAfter( + new GenericListWriter<>(arpEntryId, new ArpTerminationTableEntryCustomizer(jvpp, bdContext)), + bdId); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppStateHoneycombReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppStateHoneycombReaderFactory.java new file mode 100644 index 000000000..03da2c755 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/VppStateHoneycombReaderFactory.java @@ -0,0 +1,90 @@ +/* + * 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; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.v3po.vppstate.BridgeDomainCustomizer; +import io.fd.hc2vpp.v3po.vppstate.L2FibEntryCustomizer; +import io.fd.hc2vpp.v3po.vppstate.VersionCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericInitListReader; +import io.fd.honeycomb.translate.impl.read.GenericReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.util.read.KeepaliveReaderWrapper; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.translate.util.ReadTimeoutException; +import io.fd.hc2vpp.common.translate.util.VppStatusListener; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.ScheduledExecutorService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class VppStateHoneycombReaderFactory implements ReaderFactory { + + private final FutureJVppCore jVpp; + private final NamingContext ifcCtx; + private final NamingContext bdCtx; + private final ScheduledExecutorService keepaliveExecutor; + private final VppStatusListener vppStatusListener; + + @Inject + public VppStateHoneycombReaderFactory(final FutureJVppCore jVpp, + @Named("interface-context") final NamingContext ifcCtx, + @Named("bridge-domain-context") final NamingContext bdCtx, + final ScheduledExecutorService keepaliveExecutorDependency, + final VppStatusListener vppStatusListener) { + this.jVpp = jVpp; + this.ifcCtx = ifcCtx; + this.bdCtx = bdCtx; + this.keepaliveExecutor = keepaliveExecutorDependency; + this.vppStatusListener = vppStatusListener; + } + + @Override + public void init(final ModifiableReaderRegistryBuilder registry) { + // VppState(Structural) + final InstanceIdentifier vppStateId = InstanceIdentifier.create(VppState.class); + registry.addStructuralReader(vppStateId, VppStateBuilder.class); + // Version + // Wrap with keepalive reader to detect connection issues + // Relying on VersionCustomizer to provide a "timing out read" + registry.add(new KeepaliveReaderWrapper<>( + new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp)), + keepaliveExecutor, ReadTimeoutException.class, 30, vppStatusListener)); + // BridgeDomains(Structural) + final InstanceIdentifier bridgeDomainsId = vppStateId.child(BridgeDomains.class); + registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class); + // BridgeDomain + final InstanceIdentifier bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class); + registry.add(new GenericInitListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdCtx))); + // L2FibTable(Structural) + final InstanceIdentifier l2FibTableId = bridgeDomainId.child(L2FibTable.class); + registry.addStructuralReader(l2FibTableId, L2FibTableBuilder.class); + // L2FibEntry + registry.add(new GenericInitListReader<>(l2FibTableId.child(L2FibEntry.class), + new L2FibEntryCustomizer(jVpp, bdCtx, ifcCtx))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java new file mode 100644 index 000000000..6676956d8 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java @@ -0,0 +1,24 @@ +/* + * 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.cfgattrs; + +import net.jmob.guice.conf.core.BindConfig; +import net.jmob.guice.conf.core.Syntax; + +@BindConfig(value = "v3po", syntax = Syntax.JSON) +public class V3poConfiguration { +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/EthernetCustomizer.java new file mode 100644 index 000000000..ec83df831 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/EthernetCustomizer.java @@ -0,0 +1,58 @@ +/* + * 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; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Ethernet; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EthernetCustomizer extends FutureJVppCustomizer implements WriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class); + + public EthernetCustomizer(final FutureJVppCore vppApi) { + super(vppApi); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ethernet dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.warn("Unsupported, ignoring configuration {}", dataAfter); + // VPP API does not support setting MTU + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ethernet dataBefore, @Nonnull final Ethernet dataAfter, + @Nonnull final WriteContext writeContext) { + LOG.warn("Unsupported, ignoring configuration {}", dataAfter); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ethernet dataBefore, @Nonnull final WriteContext writeContext) { + LOG.warn("Unsupported, ignoring configuration delete {}", id); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizer.java new file mode 100644 index 000000000..b91d26364 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizer.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2016 Intel 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; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.net.InetAddresses; +import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.GreAddDelTunnel; +import io.fd.vpp.jvpp.core.dto.GreAddDelTunnelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.net.InetAddress; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +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.rev161214.GreTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GreCustomizer extends AbstractInterfaceTypeCustomizer implements JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(GreCustomizer.class); + private final NamingContext interfaceContext; + + public GreCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { + super(vppApi); + this.interfaceContext = interfaceContext; + } + + private static GreAddDelTunnel getGreTunnelRequest(final byte isAdd, final byte[] srcAddr, final byte[] dstAddr, + final int outerFibId, final byte isIpv6) { + final GreAddDelTunnel greAddDelTunnel = new GreAddDelTunnel(); + greAddDelTunnel.isAdd = isAdd; + greAddDelTunnel.srcAddress = srcAddr; + greAddDelTunnel.dstAddress = dstAddr; + greAddDelTunnel.outerFibId = outerFibId; + greAddDelTunnel.isIpv6 = isIpv6; + return greAddDelTunnel; + } + + @Override + protected Class getExpectedInterfaceType() { + return GreTunnel.class; + } + + @Override + protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Gre dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + + createGreTunnel(id, swIfName, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Gre dataBefore, + @Nonnull final Gre dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException.UpdateFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Gre tunnel update is not supported")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Gre dataBefore, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + deleteGreTunnel(id, swIfName, dataBefore, writeContext); + } + + private void createGreTunnel(final InstanceIdentifier id, final String swIfName, final Gre gre, + final WriteContext writeContext) throws WriteFailedException { + final byte isIpv6 = (byte) (isIpv6(gre) + ? 1 + : 0); + final InetAddress srcAddress = InetAddresses.forString(getAddressString(gre.getSrc())); + final InetAddress dstAddress = InetAddresses.forString(getAddressString(gre.getDst())); + + int outerFibId = gre.getOuterFibId().intValue(); + + LOG.debug("Setting gre tunnel for interface: {}. Gre: {}", swIfName, gre); + final CompletionStage greAddDelTunnelReplyCompletionStage = + getFutureJVpp().greAddDelTunnel(getGreTunnelRequest((byte) 1 /* is add */, srcAddress.getAddress(), + dstAddress.getAddress(), outerFibId, isIpv6)); + + final GreAddDelTunnelReply reply = + getReplyForCreate(greAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, gre); + LOG.debug("Gre tunnel set successfully for: {}, gre: {}", swIfName, gre); + if (interfaceContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { + // VPP keeps gre tunnels present even after they are delete(reserving ID for next tunnel) + // This may cause inconsistencies in mapping context when configuring tunnels like this: + // 1. Add tunnel 2. Delete tunnel 3. Read interfaces (reserved mapping e.g. gre_tunnel0 -> 6 + // will get into mapping context) 4. Add tunnel (this will add another mapping with the same + // reserved ID and context is invalid) + // That's why a check has to be performed here removing mapping gre_tunnel0 -> 6 mapping and storing + // new name for that ID + final String formerName = interfaceContext.getName(reply.swIfIndex, writeContext.getMappingContext()); + LOG.debug("Removing updated mapping of a gre tunnel, id: {}, former name: {}, new name: {}", + reply.swIfIndex, formerName, swIfName); + interfaceContext.removeName(formerName, writeContext.getMappingContext()); + } + // Add new interface to our interface context + interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); + } + + private boolean isIpv6(final Gre gre) { + if (gre.getSrc().getIpv4Address() == null) { + checkArgument(gre.getDst().getIpv4Address() == null, "Inconsistent ip addresses: %s, %s", gre.getSrc(), + gre.getDst()); + return true; + } else { + checkArgument(gre.getDst().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", gre.getSrc(), + gre.getDst()); + return false; + } + } + + private String getAddressString(final IpAddress addr) { + return addr.getIpv4Address() == null + ? addr.getIpv6Address().getValue() + : addr.getIpv4Address().getValue(); + } + + private void deleteGreTunnel(final InstanceIdentifier id, final String swIfName, final Gre gre, + final WriteContext writeContext) throws WriteFailedException { + final byte isIpv6 = (byte) (isIpv6(gre) + ? 1 + : 0); + final InetAddress srcAddress = InetAddresses.forString(getAddressString(gre.getSrc())); + final InetAddress dstAddress = InetAddresses.forString(getAddressString(gre.getDst())); + + int outerFibId = gre.getOuterFibId().intValue(); + + LOG.debug("Deleting gre tunnel for interface: {}. Gre: {}", swIfName, gre); + final CompletionStage greAddDelTunnelReplyCompletionStage = + getFutureJVpp().greAddDelTunnel(getGreTunnelRequest((byte) 0 /* is add */, srcAddress.getAddress(), + dstAddress.getAddress(), outerFibId, isIpv6)); + + getReplyForDelete(greAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + LOG.debug("Gre tunnel deleted successfully for: {}, gre: {}", swIfName, gre); + // Remove interface from our interface context + interfaceContext.removeName(swIfName, writeContext.getMappingContext()); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterconnectionWriteUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterconnectionWriteUtils.java new file mode 100644 index 000000000..0702717bc --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterconnectionWriteUtils.java @@ -0,0 +1,159 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; + +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Bridge; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2BridgeReply; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Xconnect; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2XconnectReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBased; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBased; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility class providing Interconnection CUD support. + */ +final class InterconnectionWriteUtils implements JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(InterconnectionWriteUtils.class); + + private final FutureJVppCore futureJVppCore; + private final NamingContext interfaceContext; + private final NamingContext bridgeDomainContext; + + InterconnectionWriteUtils(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext bridgeDomainContext) { + this.futureJVppCore = requireNonNull(futureJVppCore, "futureJVppCore should not be null"); + this.interfaceContext = requireNonNull(interfaceContext, "interfaceContext should not be null"); + this.bridgeDomainContext = requireNonNull(bridgeDomainContext, "bridgeDomainContext should not be null"); + } + + void setInterconnection(final InstanceIdentifier id, final int swIfIndex, + final String ifcName, final Interconnection ic, final WriteContext writeContext) + throws WriteFailedException { + + if (ic == null) { // TODO in case of update we should delete interconnection + LOG.trace("Interconnection is not set. Skipping"); + } else if (ic instanceof XconnectBased) { + setXconnectBasedL2(id, swIfIndex, ifcName, (XconnectBased) ic, writeContext, (byte) 1 /*enable*/); + } else if (ic instanceof BridgeBased) { + setBridgeBasedL2(id, swIfIndex, ifcName, (BridgeBased) ic, writeContext, (byte) 1 /*enable*/); + } else { + // Choices&cases are not data objects, so they cannot have a dedicated Reader/Writer + // This choice is already from augment, so its not possible to augment augmented choice + LOG.error("Unable to handle Interconnection of type {}", ic.getClass()); + throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass()); + } + } + + void deleteInterconnection(final InstanceIdentifier id, final int swIfIndex, + final String ifcName, final Interconnection ic, final WriteContext writeContext) + throws WriteFailedException { + + if (ic == null) { // TODO in case of update we should delete interconnection + LOG.trace("Interconnection is not set. Skipping"); + } else if (ic instanceof XconnectBased) { + setXconnectBasedL2(id, swIfIndex, ifcName, (XconnectBased) ic, writeContext, (byte) 0 /*disable*/); + } else if (ic instanceof BridgeBased) { + setBridgeBasedL2(id, swIfIndex, ifcName, (BridgeBased) ic, writeContext, (byte) 0 /*disable*/); + } else { + LOG.error("Unable to delete Interconnection of type {}", ic.getClass()); + throw new WriteFailedException(id, "Unable to delete Interconnection of type " + ic.getClass()); + } + } + + private void setBridgeBasedL2(final InstanceIdentifier id, final int swIfIndex, + final String ifcName, final BridgeBased bb, + final WriteContext writeContext, final byte enabled) throws WriteFailedException { + LOG.debug("Setting bridge based interconnection(bridge-domain={}) for interface: {}", bb.getBridgeDomain(), + ifcName); + + String bdName = bb.getBridgeDomain(); + + int bdId = bridgeDomainContext.getIndex(bdName, writeContext.getMappingContext()); + checkArgument(bdId > 0, "Unable to set Interconnection for Interface: %s, bridge domain: %s does not exist", + ifcName, bdName); + + byte bvi = bb.isBridgedVirtualInterface() + ? (byte) 1 + : (byte) 0; + byte shg = 0; + if (bb.getSplitHorizonGroup() != null) { + shg = bb.getSplitHorizonGroup().byteValue(); + } + + final CompletionStage swInterfaceSetL2BridgeReplyCompletionStage = futureJVppCore + .swInterfaceSetL2Bridge(getL2BridgeRequest(swIfIndex, bdId, shg, bvi, enabled)); + getReplyForWrite(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture(), id); + + LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName, bb); + } + + private SwInterfaceSetL2Bridge getL2BridgeRequest(final int swIfIndex, final int bdId, final byte shg, + final byte bvi, final byte enabled) { + final SwInterfaceSetL2Bridge swInterfaceSetL2Bridge = new SwInterfaceSetL2Bridge(); + swInterfaceSetL2Bridge.rxSwIfIndex = swIfIndex; + swInterfaceSetL2Bridge.bdId = bdId; + swInterfaceSetL2Bridge.shg = shg; + swInterfaceSetL2Bridge.bvi = bvi; + swInterfaceSetL2Bridge.enable = enabled; + return swInterfaceSetL2Bridge; + } + + private void setXconnectBasedL2(final InstanceIdentifier id, final int swIfIndex, + final String ifcName, final XconnectBased ic, + final WriteContext writeContext, final byte enabled) throws WriteFailedException { + String outSwIfName = ic.getXconnectOutgoingInterface(); + LOG.debug("Setting xconnect based interconnection(outgoing ifc={}) for interface: {}", outSwIfName, ifcName); + + int outSwIfIndex = interfaceContext.getIndex(outSwIfName, writeContext.getMappingContext()); + checkArgument(outSwIfIndex > 0, + "Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist", + ifcName, outSwIfIndex); + + final CompletionStage swInterfaceSetL2XconnectReplyCompletionStage = + futureJVppCore + .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, enabled)); + getReplyForWrite(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture(), id); + LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName, ic); + } + + private SwInterfaceSetL2Xconnect getL2XConnectRequest(final int rxIfc, final int txIfc, + final byte enabled) { + + final SwInterfaceSetL2Xconnect swInterfaceSetL2Xconnect = new SwInterfaceSetL2Xconnect(); + swInterfaceSetL2Xconnect.enable = enabled; + swInterfaceSetL2Xconnect.rxSwIfIndex = rxIfc; + swInterfaceSetL2Xconnect.txSwIfIndex = txIfc; + return swInterfaceSetL2Xconnect; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceCustomizer.java new file mode 100644 index 000000000..336a66152 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceCustomizer.java @@ -0,0 +1,121 @@ +/* + * 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; + +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +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.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlags; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Ietf interface write customizer that only caches interface objects for child writers + */ +public class InterfaceCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); + private final NamingContext interfaceContext; + + public InterfaceCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { + super(vppApi); + this.interfaceContext = interfaceContext; + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Interface dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + setInterface(id, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Interface dataBefore, + @Nonnull final Interface dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + updateInterface(id, dataBefore, dataAfter, writeContext); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Interface dataBefore, + @Nonnull final WriteContext writeContext) { + // Nothing to be done here, customizers for specific interface types e.g. vxlan handle the delete + } + + private void setInterface(final InstanceIdentifier id, final Interface swIf, + final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Setting interface: {} to: {}", id, swIf); + setInterfaceAttributes(id, swIf, swIf.getName(), writeContext); + } + + private void setInterfaceAttributes(final InstanceIdentifier id, final Interface swIf, + final String swIfName, final WriteContext writeContext) + throws WriteFailedException { + + setInterfaceFlags(id, swIfName, interfaceContext.getIndex(swIfName, writeContext.getMappingContext()), + swIf.isEnabled() + ? (byte) 1 + : (byte) 0); + } + + private void updateInterface(final InstanceIdentifier id, + final Interface dataBefore, + final Interface dataAfter, final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Updating interface:{} to: {}", id, dataAfter); + setInterfaceAttributes(id, dataAfter, dataAfter.getName(), writeContext); + } + + private void setInterfaceFlags(final InstanceIdentifier id, final String swIfName, final int swIfIndex, + final byte enabled) throws WriteFailedException { + final CompletionStage swInterfaceSetFlagsReplyFuture = + getFutureJVpp().swInterfaceSetFlags( + getSwInterfaceSetFlagsInput(swIfIndex, enabled, (byte) 0 /* deleted */)); + + LOG.debug("Updating interface flags for: {}, index: {}, enabled: {}", swIfName, swIfIndex, enabled); + + getReplyForWrite(swInterfaceSetFlagsReplyFuture.toCompletableFuture(), id); + LOG.debug("Interface flags updated successfully for: {}, index: {}, enabled: {}", + swIfName, swIfIndex, enabled); + } + + private SwInterfaceSetFlags getSwInterfaceSetFlagsInput(final int swIfIndex, final byte enabled, + final byte deleted) { + final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags(); + swInterfaceSetFlags.swIfIndex = swIfIndex; + swInterfaceSetFlags.adminUpDown = enabled; + swInterfaceSetFlags.linkUpDown = enabled; + swInterfaceSetFlags.deleted = deleted; + return swInterfaceSetFlags; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/L2Customizer.java new file mode 100644 index 000000000..cb47725b5 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/L2Customizer.java @@ -0,0 +1,89 @@ +/* + * 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; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.v3po.rev161214.interfaces._interface.L2; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class L2Customizer extends FutureJVppCustomizer implements WriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class); + private final NamingContext interfaceContext; + private final InterconnectionWriteUtils icWriteUtils; + + public L2Customizer(final FutureJVppCore vppApi, final NamingContext interfaceContext, + final NamingContext bridgeDomainContext) { + super(vppApi); + this.interfaceContext = interfaceContext; + this.icWriteUtils = new InterconnectionWriteUtils(vppApi, interfaceContext, bridgeDomainContext); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + final String ifcName = id.firstKeyOf(Interface.class).getName(); + final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); + setL2(id, swIfc, ifcName, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataBefore, + @Nonnull final L2 dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + final String ifcName = id.firstKeyOf(Interface.class).getName(); + final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); + // No update, again calling set + setL2(id, swIfc, ifcName, dataAfter, writeContext); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifcName = id.firstKeyOf(Interface.class).getName(); + final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); + deleteL2(id, swIfc, ifcName, dataBefore, writeContext); + } + + private void setL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final L2 l2, + final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Setting L2 for interface: {}", ifcName); + // Nothing besides interconnection here + icWriteUtils.setInterconnection(id, swIfIndex, ifcName, l2.getInterconnection(), writeContext); + } + + private void deleteL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final L2 l2Before, + final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Deleting L2 for interface: {}", ifcName); + // Nothing besides interconnection here + icWriteUtils.deleteInterconnection(id, swIfIndex, ifcName, l2Before.getInterconnection(), writeContext); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/LoopbackCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/LoopbackCustomizer.java new file mode 100644 index 000000000..a1b3184ed --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/LoopbackCustomizer.java @@ -0,0 +1,112 @@ +/* + * 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; + +import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.CreateLoopback; +import io.fd.vpp.jvpp.core.dto.CreateLoopbackReply; +import io.fd.vpp.jvpp.core.dto.DeleteLoopback; +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.InterfaceType; +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.rev161214.interfaces._interface.Loopback; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class LoopbackCustomizer extends AbstractInterfaceTypeCustomizer + implements MacTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(LoopbackCustomizer.class); + private final NamingContext interfaceContext; + + public LoopbackCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { + super(vppApi); + this.interfaceContext = interfaceContext; + } + + @Override + protected Class getExpectedInterfaceType() { + return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Loopback.class; + } + + @Override + protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Loopback dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String ifcName = id.firstKeyOf(Interface.class).getName(); + createLoopback(id, ifcName, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Loopback dataBefore, + @Nonnull final Loopback dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Modification of loopback interface is not supported")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Loopback dataBefore, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String ifcName = id.firstKeyOf(Interface.class).getName(); + + final int index; + try { + index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); + } catch (IllegalArgumentException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + + deleteLoopback(id, ifcName, index, dataBefore, writeContext); + } + + private void createLoopback(final InstanceIdentifier id, final String swIfName, final Loopback loopback, + final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Setting loopback interface: {}. Loopback: {}", swIfName, loopback); + + final CreateLoopback createLoopback = new CreateLoopback(); + if (loopback.getMac() != null) { + createLoopback.macAddress = parseMac(loopback.getMac().getValue()); + } + final CreateLoopbackReply reply = + getReplyForCreate(getFutureJVpp().createLoopback(createLoopback).toCompletableFuture(), id, loopback); + + LOG.debug("Loopback set successfully for: {}, loopback: {}", swIfName, loopback); + // Add new interface to our interface context + interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); + } + + private void deleteLoopback(final InstanceIdentifier id, final String swIfName, final int index, + final Loopback dataBefore, final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Deleting loopback interface: {}. Loopback: {}", swIfName, dataBefore); + final DeleteLoopback deleteLoopback = new DeleteLoopback(); + deleteLoopback.swIfIndex = index; + getReplyForDelete(getFutureJVpp().deleteLoopback(deleteLoopback).toCompletableFuture(), id); + LOG.debug("Loopback deleted successfully for: {}, loopback: {}", swIfName, dataBefore); + // Remove deleted interface from interface context + interfaceContext.removeName(swIfName, writeContext.getMappingContext()); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizer.java new file mode 100644 index 000000000..66f2e3e81 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizer.java @@ -0,0 +1,108 @@ +/* + * 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; + +import com.google.common.net.InetAddresses; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ProxyArpAddDel; +import io.fd.vpp.jvpp.core.dto.ProxyArpAddDelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.net.InetAddress; +import java.util.concurrent.Future; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArp; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCustomizer, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class); + + public ProxyArpCustomizer(final FutureJVppCore vppApi) { + super(vppApi); + } + + @Override + public void writeCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + createProxyArp(getProxyArpRequestFuture(id, swIfName, dataAfter, (byte) 1 /* 1 is add */), id, dataAfter); + } + + @Override + public void updateCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataBefore, + @Nonnull ProxyArp dataAfter, @Nonnull WriteContext writeContext) + throws WriteFailedException.UpdateFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("ARP proxy update is not supported")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataBefore, + @Nonnull WriteContext writeContext) throws WriteFailedException { + + final String swIfName = id.firstKeyOf(Interface.class).getName(); + deleteProxyArp(getProxyArpRequestFuture(id, swIfName, dataBefore, (byte) 0 /* 0 is delete */), id); + } + + private Future getProxyArpRequestFuture(InstanceIdentifier id, String swIfName, + ProxyArp proxyArp, byte operation) + throws WriteFailedException { + LOG.debug("Setting Proxy ARP settings for interface: {}", swIfName); + final InetAddress srcAddress = InetAddresses.forString(getv4AddressString(proxyArp.getLowAddr())); + final InetAddress dstAddress = InetAddresses.forString(getv4AddressString(proxyArp.getHighAddr())); + final int vrfId = proxyArp.getVrfId().intValue(); + return getFutureJVpp().proxyArpAddDel( + getProxyArpConfRequest(operation, srcAddress.getAddress(), dstAddress.getAddress(), vrfId)) + .toCompletableFuture(); + } + + private void createProxyArp(final Future future, final InstanceIdentifier identifier, + final ProxyArp data) + throws WriteFailedException { + final ProxyArpAddDelReply reply = getReplyForCreate(future, identifier, data); + LOG.debug("Proxy ARP setting create successful, with reply context:", reply.context); + } + + private void deleteProxyArp(final Future future, final InstanceIdentifier identifier) + throws WriteFailedException { + final ProxyArpAddDelReply reply = getReplyForDelete(future, identifier); + LOG.debug("Proxy ARP setting delete successful, with reply context:", reply.context); + } + + private static ProxyArpAddDel getProxyArpConfRequest(final byte isAdd, final byte[] lAddr, final byte[] hAddr, + final int vrfId) { + + final ProxyArpAddDel proxyArpAddDel = new ProxyArpAddDel(); + proxyArpAddDel.isAdd = isAdd; + proxyArpAddDel.lowAddress = lAddr; + proxyArpAddDel.hiAddress = hAddr; + proxyArpAddDel.vrfId = vrfId; + return proxyArpAddDel; + } + + private String getv4AddressString(@Nonnull final Ipv4Address addr) { + return addr.getValue(); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizer.java new file mode 100644 index 000000000..4ad632166 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizer.java @@ -0,0 +1,136 @@ +/* + * 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; + +import com.google.common.base.Preconditions; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +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.util.SubInterfaceUtils; +import io.fd.hc2vpp.common.translate.util.TagRewriteOperation; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.L2InterfaceVlanTagRewrite; +import io.fd.vpp.jvpp.core.dto.L2InterfaceVlanTagRewriteReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.concurrent.CompletionStage; +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.vlan.rev161214._802dot1q; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.RewriteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer Customizer responsible for vlan tag rewrite.
Sends {@code l2_interface_vlan_tag_rewrite} message to + * VPP.
Equivalent of invoking {@code vppctl set interface l2 tag-rewrite} command. + */ +public class RewriteCustomizer extends FutureJVppCustomizer + implements WriterCustomizer, ByteDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class); + private final NamingContext interfaceContext; + + public RewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void writeCurrentAttributes(final InstanceIdentifier id, final Rewrite dataAfter, + final WriteContext writeContext) + throws WriteFailedException { + final String subifName = getSubInterfaceName(id); + setTagRewrite(id, subifName, dataAfter, writeContext); + } + + private static String getSubInterfaceName(final InstanceIdentifier id) { + return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), + Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier())); + } + + private void setTagRewrite(final InstanceIdentifier id, final String ifname, final Rewrite rewrite, + final WriteContext writeContext) throws WriteFailedException { + final int swIfIndex = interfaceContext.getIndex(ifname, writeContext.getMappingContext()); + LOG.debug("Setting tag rewrite for interface {}(id=): {}", ifname, swIfIndex, rewrite); + + final CompletionStage replyCompletionStage = + getFutureJVpp().l2InterfaceVlanTagRewrite(getTagRewriteRequest(swIfIndex, rewrite)); + + getReplyForWrite(replyCompletionStage.toCompletableFuture(), id); + LOG.debug("Tag rewrite for interface {}(id=) set successfully: {}", ifname, swIfIndex, rewrite); + } + + private L2InterfaceVlanTagRewrite getTagRewriteRequest(final int swIfIndex, final Rewrite rewrite) { + final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite(); + request.swIfIndex = swIfIndex; + request.pushDot1Q = booleanToByte(_802dot1q.class == rewrite.getVlanType()); + + final List pushTags = rewrite.getPushTags(); + final Short popTags = rewrite.getPopTags(); + + final int numberOfTagsToPop = popTags == null + ? 0 + : popTags.intValue(); + final int numberOfTagsToPush = pushTags == null + ? 0 + : pushTags.size(); + + request.vtrOp = TagRewriteOperation.get(numberOfTagsToPop, numberOfTagsToPush).ordinal(); + + if (numberOfTagsToPush > 0) { + for (final PushTags tag : pushTags) { + if (tag.getIndex() == 0) { + request.tag1 = tag.getDot1qTag().getVlanId().getValue(); + } else { + request.tag2 = tag.getDot1qTag().getVlanId().getValue(); + } + } + } + + LOG.debug("Generated tag rewrite request: {}", request); + return request; + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Rewrite dataBefore, + @Nonnull final Rewrite dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String subifName = getSubInterfaceName(id); + setTagRewrite(id, subifName, dataAfter, writeContext); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Rewrite dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String subifName = getSubInterfaceName(id); + + LOG.debug("Disabling tag rewrite for interface {}", subifName); + final Rewrite rewrite = new RewriteBuilder().build(); // rewrite without push and pops will cause delete + setTagRewrite(id, subifName, rewrite, writeContext); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RoutingCustomizer.java new file mode 100644 index 000000000..574fcebec --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RoutingCustomizer.java @@ -0,0 +1,122 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +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.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetTable; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetTableReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +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.v3po.rev161214.interfaces._interface.Routing; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RoutingCustomizer extends FutureJVppCustomizer implements WriterCustomizer, JvppReplyConsumer, + ByteDataTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(RoutingCustomizer.class); + private final NamingContext interfaceContext; + + public RoutingCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { + super(vppApi); + this.interfaceContext = interfaceContext; + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + final String ifName = id.firstKeyOf(Interface.class).getName(); + setRouting(id, ifName, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Routing dataBefore, @Nonnull final Routing dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + final String ifName = id.firstKeyOf(Interface.class).getName(); + setRouting(id, ifName, dataAfter, writeContext); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Routing dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + disableRouting(id, ifName, writeContext); + } + + private void setRouting(@Nonnull final InstanceIdentifier id, @Nonnull final String name, + @Nonnull final Routing rt, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final int swIfc = interfaceContext.getIndex(name, writeContext.getMappingContext()); + LOG.debug("Setting routing for interface: {}, {}. Routing: {}", name, swIfc, rt); + checkArgument(rt.getIpv4VrfId() != null || rt.getIpv6VrfId() != null, "No vrf-id given"); + + setVrfId(id, swIfc, rt.getIpv4VrfId(), false); + setVrfId(id, swIfc, rt.getIpv6VrfId(), true); + + LOG.debug("Routing set successfully for interface: {}, {}, routing: {}", name, swIfc, rt); + } + + private void setVrfId(final InstanceIdentifier id, final int swIfc, final Long vrfId, boolean isIp6) + throws WriteFailedException { + if (vrfId == null) { + return; + } + final CompletionStage cs = getFutureJVpp() + .swInterfaceSetTable(getInterfaceSetTableRequest(swIfc, booleanToByte(isIp6), vrfId.intValue())); + getReplyForWrite(cs.toCompletableFuture(), id); + } + + /** + * In this case, there is no such thing as delete routing,only thing that can be done is to disable it by setting + * default value 0 + */ + private void disableRouting(final InstanceIdentifier id, final String name, + final WriteContext writeContext) throws WriteFailedException { + final int swIfc = interfaceContext.getIndex(name, writeContext.getMappingContext()); + LOG.debug("Disabling routing for interface: {}, {}.", name, swIfc); + + getReplyForDelete(getFutureJVpp() + .swInterfaceSetTable(getInterfaceSetTableRequest(swIfc, (byte) 0, 0)).toCompletableFuture(), id); + LOG.debug("Routing for interface: {}, {} successfully disabled", name, swIfc); + + } + + private SwInterfaceSetTable getInterfaceSetTableRequest(final int swIfc, final byte isIpv6, final int vrfId) { + final SwInterfaceSetTable swInterfaceSetTable = new SwInterfaceSetTable(); + swInterfaceSetTable.isIpv6 = isIpv6; + swInterfaceSetTable.swIfIndex = swIfc; + swInterfaceSetTable.vrfId = vrfId; + return swInterfaceSetTable; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizer.java new file mode 100644 index 000000000..c39cfa6ec --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizer.java @@ -0,0 +1,193 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkState; +import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getNumberOfTags; +import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName; + +import com.google.common.base.Preconditions; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +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.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.CreateSubif; +import io.fd.vpp.jvpp.core.dto.CreateSubifReply; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlags; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan; +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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1ad; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.MatchType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.Default; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTagged; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer Customizer responsible for sub interface creation.
Sends {@code create_subif} message to VPP.
+ * Equivalent of invoking {@code vppclt create subif} command. + */ +public class SubInterfaceCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class); + private final NamingContext interfaceContext; + + public SubInterfaceCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final SubInterface dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String superIfName = id.firstKeyOf(Interface.class).getName(); + createSubInterface(id, superIfName, dataAfter, writeContext); + } + + private void createSubInterface(final InstanceIdentifier id, @Nonnull final String superIfName, + @Nonnull final SubInterface subInterface, final WriteContext writeContext) + throws WriteFailedException { + final int superIfIndex = interfaceContext.getIndex(superIfName, writeContext.getMappingContext()); + final CompletionStage createSubifReplyCompletionStage = + getFutureJVpp().createSubif(getCreateSubifRequest(subInterface, superIfIndex)); + + final CreateSubifReply reply = + getReplyForCreate(createSubifReplyCompletionStage.toCompletableFuture(), id, subInterface); + + setInterfaceState(id, reply.swIfIndex, booleanToByte(subInterface.isEnabled())); + interfaceContext.addName(reply.swIfIndex, + getSubInterfaceName(superIfName, Math.toIntExact(subInterface.getIdentifier())), + writeContext.getMappingContext()); + LOG.debug("Sub interface created successfully for: {}, subInterface: {}", superIfName, subInterface); + } + + private CreateSubif getCreateSubifRequest(@Nonnull final SubInterface subInterface, final int swIfIndex) { + // TODO HONEYCOMB-183 add validation + CreateSubif request = new CreateSubif(); + request.subId = Math.toIntExact(subInterface.getIdentifier().intValue()); + request.swIfIndex = swIfIndex; + + final int numberOfTags = getNumberOfTags(subInterface.getTags()); + switch (numberOfTags) { + case 0: + request.noTags = 1; + break; + case 1: + request.oneTag = 1; + break; + case 2: + request.twoTags = 1; + break; + } + request.dot1Ad = booleanToByte(_802dot1ad.class == subInterface.getVlanType()); + + // TODO HONEYCOMB-183 match should be mandatory + final MatchType matchType = subInterface.getMatch().getMatchType(); + request.exactMatch = + booleanToByte(matchType instanceof VlanTagged && ((VlanTagged) matchType).isMatchExactTags()); + request.defaultSub = booleanToByte(matchType instanceof Default); + + if (numberOfTags > 0) { + for (final Tag tag : subInterface.getTags().getTag()) { + if (tag.getIndex() == 0) { + setOuterTag(request, tag); + } else if (tag.getIndex() == 1) { + setInnerTag(request, tag); + } + } + } + return request; + } + + private void setOuterTag(final CreateSubif request, final Tag outerTag) { + checkState(SVlan.class == outerTag.getDot1qTag().getTagType(), "Service Tag expected at index 0"); + final Dot1qTag.VlanId vlanId = outerTag.getDot1qTag().getVlanId(); + + request.outerVlanId = dot1qVlanIdToShort(vlanId.getDot1qVlanId()); + request.outerVlanIdAny = booleanToByte(Dot1qTag.VlanId.Enumeration.Any.equals(vlanId.getEnumeration())); + } + + private void setInnerTag(final CreateSubif request, final Tag innerTag) { + checkState(CVlan.class == innerTag.getDot1qTag().getTagType(), "Customer Tag expected at index 1"); + final Dot1qTag.VlanId vlanId = innerTag.getDot1qTag().getVlanId(); + + request.innerVlanId = dot1qVlanIdToShort(vlanId.getDot1qVlanId()); + request.innerVlanIdAny = booleanToByte(Dot1qTag.VlanId.Enumeration.Any.equals(vlanId.getEnumeration())); + } + + private static short dot1qVlanIdToShort(@Nullable Dot1qVlanId dot1qVlanId) { + if (dot1qVlanId == null) { + return 0; // tell VPP that optional argument is missing + } else { + return dot1qVlanId.getValue().shortValue(); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final SubInterface dataBefore, @Nonnull final SubInterface dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String subIfaceName = getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), + Math.toIntExact(dataAfter.getIdentifier())); + setInterfaceState(id, interfaceContext.getIndex(subIfaceName, writeContext.getMappingContext()), + booleanToByte(dataAfter.isEnabled())); + } + + private void setInterfaceState(final InstanceIdentifier id, final int swIfIndex, final byte enabled) + throws WriteFailedException { + final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags(); + swInterfaceSetFlags.swIfIndex = swIfIndex; + swInterfaceSetFlags.adminUpDown = enabled; + + final CompletionStage swInterfaceSetFlagsReplyFuture = + getFutureJVpp().swInterfaceSetFlags(swInterfaceSetFlags); + + LOG.debug("Updating interface state for interface if={}, enabled: {}", swIfIndex, enabled); + + SwInterfaceSetFlagsReply reply = + getReplyForWrite(swInterfaceSetFlagsReplyFuture.toCompletableFuture(), id); + LOG.debug("Interface state updated successfully for interface index: {}, enabled: {}, ctxId: {}", + swIfIndex, enabled, reply.context); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final SubInterface dataBefore, + @Nonnull final WriteContext writeContext) + throws WriteFailedException.DeleteFailedException { + throw new UnsupportedOperationException("Sub interface delete is not supported"); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2Customizer.java new file mode 100644 index 000000000..4a3e4435d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2Customizer.java @@ -0,0 +1,100 @@ +/* + * 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; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for writing vlan sub interface l2 configuration + */ +public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements WriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class); + private final NamingContext interfaceContext; + private final InterconnectionWriteUtils icWriterUtils; + + public SubInterfaceL2Customizer(final FutureJVppCore vppApi, final NamingContext interfaceContext, + final NamingContext bridgeDomainContext) { + super(vppApi); + this.interfaceContext = interfaceContext; + this.icWriterUtils = new InterconnectionWriteUtils(vppApi, interfaceContext, bridgeDomainContext); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext); + } + + private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + return SubInterfaceUtils + .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataBefore, + @Nonnull final L2 dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + // Setting L2 to new values + setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + deleteL2(id, subInterfaceIndex, subInterfaceName, dataBefore, writeContext); + } + + private void setL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final L2 l2, + final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Setting L2 for sub-interface: {}", ifcName); + icWriterUtils.setInterconnection(id, swIfIndex, ifcName, l2.getInterconnection(), writeContext); + } + + private void deleteL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final L2 l2Before, + final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Deleting L2 for sub-interface: {}", ifcName); + icWriterUtils.deleteInterconnection(id, swIfIndex, ifcName, l2Before.getInterconnection(), writeContext); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/TapCustomizer.java new file mode 100644 index 000000000..220fb95e8 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/TapCustomizer.java @@ -0,0 +1,182 @@ +/* + * 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; + +import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.TapConnect; +import io.fd.vpp.jvpp.core.dto.TapConnectReply; +import io.fd.vpp.jvpp.core.dto.TapDelete; +import io.fd.vpp.jvpp.core.dto.TapDeleteReply; +import io.fd.vpp.jvpp.core.dto.TapModify; +import io.fd.vpp.jvpp.core.dto.TapModifyReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +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.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TapCustomizer extends AbstractInterfaceTypeCustomizer implements MacTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class); + private final NamingContext interfaceContext; + + public TapCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { + super(vppApi); + this.interfaceContext = interfaceContext; + } + + @Override + protected Class getExpectedInterfaceType() { + return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap.class; + } + + @Override + protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Tap dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String ifcName = id.firstKeyOf(Interface.class).getName(); + createTap(id, ifcName, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Tap dataBefore, + @Nonnull final Tap dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String ifcName = id.firstKeyOf(Interface.class).getName(); + + final int index; + try { + index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); + } catch (IllegalArgumentException e) { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); + } + + modifyTap(id, ifcName, index, dataBefore, dataAfter); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Tap dataBefore, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String ifcName = id.firstKeyOf(Interface.class).getName(); + + final int index; + try { + index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); + } catch (IllegalArgumentException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + + deleteTap(id, ifcName, index, dataBefore, writeContext); + } + + private void createTap(final InstanceIdentifier id, final String swIfName, final Tap tap, + final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Setting tap interface: {}. Tap: {}", swIfName, tap); + final CompletionStage tapConnectFuture = getFutureJVpp() + .tapConnect(getTapConnectRequest(tap.getTapName(), tap.getMac(), tap.getDeviceInstance())); + final TapConnectReply reply = getReplyForCreate(tapConnectFuture.toCompletableFuture(), id, tap); + LOG.debug("Tap set successfully for: {}, tap: {}", swIfName, tap); + // Add new interface to our interface context + interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); + } + + private void modifyTap(final InstanceIdentifier id, final String swIfName, final int index, + final Tap tapBefore, final Tap tapAfter) throws WriteFailedException { + LOG.debug("Modifying tap interface: {}. Tap: {}", swIfName, tapAfter); + final CompletionStage vxlanAddDelTunnelReplyCompletionStage = + getFutureJVpp() + .tapModify(getTapModifyRequest(tapAfter.getTapName(), index, tapAfter.getMac(), + tapAfter.getDeviceInstance())); + getReplyForUpdate(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, tapBefore, tapAfter); + LOG.debug("Tap modified successfully for: {}, tap: {}", swIfName, tapAfter); + } + + private void deleteTap(final InstanceIdentifier id, final String swIfName, final int index, + final Tap dataBefore, final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Deleting tap interface: {}. Tap: {}", swIfName, dataBefore); + final CompletionStage vxlanAddDelTunnelReplyCompletionStage = + getFutureJVpp().tapDelete(getTapDeleteRequest(index)); + getReplyForDelete(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + LOG.debug("Tap deleted successfully for: {}, tap: {}", swIfName, dataBefore); + // Remove deleted interface from interface context + interfaceContext.removeName(swIfName, writeContext.getMappingContext()); + } + + private TapConnect getTapConnectRequest(final String tapName, final PhysAddress mac, final Long deviceInstance) { + final TapConnect tapConnect = new TapConnect(); + tapConnect.tapName = tapName.getBytes(); + + if (mac == null) { + tapConnect.useRandomMac = 1; + tapConnect.macAddress = new byte[6]; + } else { + tapConnect.useRandomMac = 0; + tapConnect.macAddress = parseMac(mac.getValue()); + } + + if (deviceInstance == null) { + tapConnect.renumber = 0; + } else { + tapConnect.renumber = 1; + tapConnect.customDevInstance = Math.toIntExact(deviceInstance); + } + + return tapConnect; + } + + private TapModify getTapModifyRequest(final String tapName, final int swIndex, final PhysAddress mac, + final Long deviceInstance) { + final TapModify tapConnect = new TapModify(); + tapConnect.tapName = tapName.getBytes(); + tapConnect.swIfIndex = swIndex; + + if (mac == null) { + tapConnect.useRandomMac = 1; + tapConnect.macAddress = new byte[6]; + } else { + tapConnect.useRandomMac = 0; + tapConnect.macAddress = parseMac(mac.getValue()); + } + + if (deviceInstance == null) { + tapConnect.renumber = 0; + } else { + tapConnect.renumber = 1; + tapConnect.customDevInstance = Math.toIntExact(deviceInstance); + } + + return tapConnect; + } + + private TapDelete getTapDeleteRequest(final int swIndex) { + final TapDelete tapConnect = new TapDelete(); + tapConnect.swIfIndex = swIndex; + return tapConnect; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizer.java new file mode 100644 index 000000000..dc8fade2b --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizer.java @@ -0,0 +1,157 @@ +/* + * 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; + +import com.google.common.base.Preconditions; +import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.CreateVhostUserIf; +import io.fd.vpp.jvpp.core.dto.CreateVhostUserIfReply; +import io.fd.vpp.jvpp.core.dto.DeleteVhostUserIf; +import io.fd.vpp.jvpp.core.dto.DeleteVhostUserIfReply; +import io.fd.vpp.jvpp.core.dto.ModifyVhostUserIf; +import io.fd.vpp.jvpp.core.dto.ModifyVhostUserIfReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +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.rev161214.VhostUserRole; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer Customizer responsible for passing vhost user interface CRD operations to VPP + */ +public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer + implements ByteDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class); + private final NamingContext interfaceContext; + + public VhostUserCustomizer(@Nonnull final FutureJVppCore vppApi, @Nonnull final NamingContext interfaceContext) { + super(vppApi); + this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + protected Class getExpectedInterfaceType() { + return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser.class; + } + + @Override + protected final void writeInterface(@Nonnull final InstanceIdentifier id, + @Nonnull final VhostUser dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + createVhostUserIf(id, swIfName, dataAfter, writeContext); + } + + private void createVhostUserIf(final InstanceIdentifier id, final String swIfName, + final VhostUser vhostUser, final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Creating vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); + + final CompletionStage createVhostUserIfReplyCompletionStage = + getFutureJVpp().createVhostUserIf(getCreateVhostUserIfRequest(vhostUser)); + final CreateVhostUserIfReply reply = + getReplyForCreate(createVhostUserIfReplyCompletionStage.toCompletableFuture(), id, vhostUser); + LOG.debug("Vhost user interface created successfully for: {}, vhostUser: {}", swIfName, vhostUser); + // Add new interface to our interface context + interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); + } + + private CreateVhostUserIf getCreateVhostUserIfRequest(final VhostUser vhostUser) { + CreateVhostUserIf request = new CreateVhostUserIf(); + request.isServer = booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())); + request.sockFilename = vhostUser.getSocket().getBytes(); + // TODO HONEYCOMB-177 expose device instance attribute just like for TAP + request.renumber = 0; + request.customDevInstance = 0; + request.useCustomMac = 0; + request.macAddress = new byte[]{}; + return request; + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final VhostUser dataBefore, @Nonnull final VhostUser dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + modifyVhostUserIf(id, swIfName, dataBefore, dataAfter, writeContext); + } + + private void modifyVhostUserIf(final InstanceIdentifier id, final String swIfName, + final VhostUser vhostUserBefore, final VhostUser vhostUserAfter, + final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Updating vhost user interface: name={}, vhostUser={}", swIfName, vhostUserAfter); + final CompletionStage modifyVhostUserIfReplyCompletionStage = + getFutureJVpp() + .modifyVhostUserIf(getModifyVhostUserIfRequest(vhostUserAfter, + interfaceContext.getIndex(swIfName, writeContext.getMappingContext()))); + + getReplyForUpdate(modifyVhostUserIfReplyCompletionStage.toCompletableFuture(), id, vhostUserBefore, + vhostUserAfter); + LOG.debug("Vhost user interface updated successfully for: {}, vhostUser: {}", swIfName, vhostUserAfter); + } + + private ModifyVhostUserIf getModifyVhostUserIfRequest(final VhostUser vhostUser, final int swIfIndex) { + ModifyVhostUserIf request = new ModifyVhostUserIf(); + request.isServer = booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())); + request.sockFilename = vhostUser.getSocket().getBytes(); + // TODO HONEYCOMB-177 + request.renumber = 0; + request.customDevInstance = 0; + request.swIfIndex = swIfIndex; + return request; + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final VhostUser dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + deleteVhostUserIf(id, swIfName, dataBefore, writeContext); + } + + private void deleteVhostUserIf(final InstanceIdentifier id, final String swIfName, + final VhostUser vhostUser, final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Deleting vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); + final CompletionStage deleteVhostUserIfReplyCompletionStage = + getFutureJVpp().deleteVhostUserIf(getDeleteVhostUserIfRequest( + interfaceContext.getIndex(swIfName, writeContext.getMappingContext()))); + + getReplyForDelete(deleteVhostUserIfReplyCompletionStage.toCompletableFuture(), id); + LOG.debug("Vhost user interface deleted successfully for: {}, vhostUser: {}", swIfName, vhostUser); + // Remove interface from our interface context + interfaceContext.removeName(swIfName, writeContext.getMappingContext()); + } + + private DeleteVhostUserIf getDeleteVhostUserIfRequest(final int swIfIndex) { + DeleteVhostUserIf request = new DeleteVhostUserIf(); + request.swIfIndex = swIfIndex; + return request; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizer.java new file mode 100644 index 000000000..ec2193476 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizer.java @@ -0,0 +1,192 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.net.InetAddresses; +import io.fd.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.VxlanAddDelTunnel; +import io.fd.vpp.jvpp.core.dto.VxlanAddDelTunnelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.net.InetAddress; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +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.rev161214.VxlanTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer implements JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class); + + private final NamingContext interfaceNamingContext; + private final DisabledInterfacesManager interfaceDisableContext; + + public VxlanCustomizer(@Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceNamingContext, + @Nonnull final DisabledInterfacesManager interfaceDisableContext) { + super(vppApi); + this.interfaceNamingContext = interfaceNamingContext; + this.interfaceDisableContext = interfaceDisableContext; + } + + @Override + protected Class getExpectedInterfaceType() { + return VxlanTunnel.class; + } + + @Override + protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Vxlan dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + createVxlanTunnel(id, swIfName, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Vxlan dataBefore, + @Nonnull final Vxlan dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException.UpdateFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Vxlan tunnel update is not supported")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Vxlan dataBefore, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + deleteVxlanTunnel(id, swIfName, dataBefore, writeContext); + } + + private void createVxlanTunnel(final InstanceIdentifier id, final String swIfName, final Vxlan vxlan, + final WriteContext writeContext) + throws WriteFailedException { + final byte isIpv6 = (byte) (isIpv6(vxlan) + ? 1 + : 0); + final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc())); + final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst())); + + int encapVrfId = vxlan.getEncapVrfId().intValue(); + int vni = vxlan.getVni().getValue().intValue(); + + LOG.debug("Setting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan); + final CompletionStage vxlanAddDelTunnelReplyCompletionStage = + getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 1 /* is add */, srcAddress.getAddress(), + dstAddress.getAddress(), encapVrfId, -1, vni, isIpv6)); + + final VxlanAddDelTunnelReply reply = + getReplyForCreate(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, vxlan); + LOG.debug("Vxlan tunnel set successfully for: {}, vxlan: {}", swIfName, vxlan); + if (interfaceNamingContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { + // VPP keeps vxlan tunnels present even after they are delete(reserving ID for next tunnel) + // This may cause inconsistencies in mapping context when configuring tunnels like this: + // 1. Add tunnel 2. Delete tunnel 3. Read interfaces (reserved mapping e.g. vxlan_tunnel0 -> 6 + // will get into mapping context) 4. Add tunnel (this will add another mapping with the same + // reserved ID and context is invalid) + // That's why a check has to be performed here removing mapping vxlan_tunnel0 -> 6 mapping and storing + // new name for that ID + final String formerName = interfaceNamingContext.getName(reply.swIfIndex, writeContext.getMappingContext()); + LOG.debug("Removing updated mapping of a vxlan tunnel, id: {}, former name: {}, new name: {}", + reply.swIfIndex, formerName, swIfName); + interfaceNamingContext.removeName(formerName, writeContext.getMappingContext()); + + } + + // Removing disability of an interface in case a vxlan tunnel formerly deleted is being reused in VPP + // further details in above comment + if (interfaceDisableContext.isInterfaceDisabled(reply.swIfIndex, writeContext.getMappingContext())) { + LOG.debug("Removing disability of vxlan tunnel, id: {}, name: {}", reply.swIfIndex, swIfName); + interfaceDisableContext.removeDisabledInterface(reply.swIfIndex, writeContext.getMappingContext()); + } + + // Add new interface to our interface context + interfaceNamingContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); + } + + private boolean isIpv6(final Vxlan vxlan) { + if (vxlan.getSrc().getIpv4Address() == null) { + checkArgument(vxlan.getDst().getIpv4Address() == null, "Inconsistent ip addresses: %s, %s", vxlan.getSrc(), + vxlan.getDst()); + return true; + } else { + checkArgument(vxlan.getDst().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", vxlan.getSrc(), + vxlan.getDst()); + return false; + } + } + + private String getAddressString(final IpAddress addr) { + return addr.getIpv4Address() == null + ? addr.getIpv6Address().getValue() + : addr.getIpv4Address().getValue(); + } + + private void deleteVxlanTunnel(final InstanceIdentifier id, final String swIfName, final Vxlan vxlan, + final WriteContext writeContext) throws WriteFailedException { + final byte isIpv6 = (byte) (isIpv6(vxlan) + ? 1 + : 0); + final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc())); + final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst())); + + int encapVrfId = vxlan.getEncapVrfId().intValue(); + int vni = vxlan.getVni().getValue().intValue(); + + LOG.debug("Deleting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan); + final CompletionStage vxlanAddDelTunnelReplyCompletionStage = + getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 0 /* is add */, srcAddress.getAddress(), + dstAddress.getAddress(), encapVrfId, -1, vni, isIpv6)); + + getReplyForDelete(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + LOG.debug("Vxlan tunnel deleted successfully for: {}, vxlan: {}", swIfName, vxlan); + + final int index = interfaceNamingContext.getIndex(swIfName, writeContext.getMappingContext()); + // Mark this interface as disabled to not include it in operational reads + // because VPP will keep the interface there + LOG.debug("Marking vxlan tunnel as disabled, id: {}, name: {}", index, swIfName); + interfaceDisableContext.disableInterface(index, writeContext.getMappingContext()); + // Remove interface from our interface naming context + interfaceNamingContext.removeName(swIfName, writeContext.getMappingContext()); + } + + private static VxlanAddDelTunnel getVxlanTunnelRequest(final byte isAdd, final byte[] srcAddr, final byte[] dstAddr, + final int encapVrfId, + final int decapNextIndex, final int vni, final byte isIpv6) { + final VxlanAddDelTunnel vxlanAddDelTunnel = new VxlanAddDelTunnel(); + vxlanAddDelTunnel.isAdd = isAdd; + vxlanAddDelTunnel.srcAddress = srcAddr; + vxlanAddDelTunnel.dstAddress = dstAddr; + vxlanAddDelTunnel.encapVrfId = encapVrfId; + vxlanAddDelTunnel.vni = vni; + vxlanAddDelTunnel.decapNextIndex = decapNextIndex; + vxlanAddDelTunnel.isIpv6 = isIpv6; + return vxlanAddDelTunnel; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizer.java new file mode 100644 index 000000000..59ec958f2 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizer.java @@ -0,0 +1,194 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.net.InetAddresses; +import io.fd.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.VxlanGpeAddDelTunnel; +import io.fd.vpp.jvpp.core.dto.VxlanGpeAddDelTunnelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.net.InetAddress; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +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.rev161214.VxlanGpeTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer implements JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class); + private final NamingContext interfaceNamingContext; + private final DisabledInterfacesManager interfaceDisableContext; + + public VxlanGpeCustomizer(@Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceNamingContext, + @Nonnull final DisabledInterfacesManager interfaceDisableContext) { + super(vppApi); + this.interfaceNamingContext = interfaceNamingContext; + this.interfaceDisableContext = interfaceDisableContext; + } + + @Override + protected Class getExpectedInterfaceType() { + return VxlanGpeTunnel.class; + } + + @Override + protected final void writeInterface(@Nonnull final InstanceIdentifier id, + @Nonnull final VxlanGpe dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + createVxlanGpeTunnel(id, swIfName, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final VxlanGpe dataBefore, + @Nonnull final VxlanGpe dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException.UpdateFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("VxlanGpe tunnel update is not supported")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final VxlanGpe dataBefore, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + deleteVxlanGpeTunnel(id, swIfName, dataBefore, writeContext); + } + + private void createVxlanGpeTunnel(final InstanceIdentifier id, final String swIfName, + final VxlanGpe vxlanGpe, final WriteContext writeContext) + throws WriteFailedException { + final byte isIpv6 = (byte) (isIpv6(vxlanGpe) + ? 1 + : 0); + final InetAddress Local = InetAddresses.forString(getAddressString(vxlanGpe.getLocal())); + final InetAddress Remote = InetAddresses.forString(getAddressString(vxlanGpe.getRemote())); + + int vni = vxlanGpe.getVni().getValue().intValue(); + byte protocol = (byte) vxlanGpe.getNextProtocol().getIntValue(); + int encapVrfId = vxlanGpe.getEncapVrfId().intValue(); + int decapVrfId = vxlanGpe.getDecapVrfId().intValue(); + + LOG.debug("Setting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, vxlanGpe); + final CompletionStage VxlanGpeAddDelTunnelReplyCompletionStage = + getFutureJVpp().vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 1 /* is add */, Local.getAddress(), + Remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); + + final VxlanGpeAddDelTunnelReply reply = + getReplyForCreate(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, vxlanGpe); + LOG.debug("VxlanGpe tunnel set successfully for: {}, VxlanGpe: {}", swIfName, vxlanGpe); + if (interfaceNamingContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { + final String formerName = interfaceNamingContext.getName(reply.swIfIndex, writeContext.getMappingContext()); + LOG.debug("Removing updated mapping of a vxlan-gpe tunnel, id: {}, former name: {}, new name: {}", + reply.swIfIndex, formerName, swIfName); + interfaceNamingContext.removeName(formerName, writeContext.getMappingContext()); + } + + // Removing disability of an interface in case a vxlan-gpe tunnel formerly deleted is being reused in VPP + // further details in above comment + if (interfaceDisableContext.isInterfaceDisabled(reply.swIfIndex, writeContext.getMappingContext())) { + LOG.debug("Removing disability of vxlan tunnel, id: {}, name: {}", reply.swIfIndex, swIfName); + interfaceDisableContext.removeDisabledInterface(reply.swIfIndex, writeContext.getMappingContext()); + } + + // Add new interface to our interface context + interfaceNamingContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); + } + + private boolean isIpv6(final VxlanGpe vxlanGpe) { + if (vxlanGpe.getLocal().getIpv4Address() == null) { + checkArgument(vxlanGpe.getRemote().getIpv4Address() == null, "Inconsistent ip addresses: %s, %s", + vxlanGpe.getLocal(), + vxlanGpe.getRemote()); + return true; + } else { + checkArgument(vxlanGpe.getRemote().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", + vxlanGpe.getLocal(), + vxlanGpe.getRemote()); + return false; + } + } + + private String getAddressString(final IpAddress addr) { + return addr.getIpv4Address() == null + ? addr.getIpv6Address().getValue() + : addr.getIpv4Address().getValue(); + } + + private void deleteVxlanGpeTunnel(final InstanceIdentifier id, final String swIfName, + final VxlanGpe vxlanGpe, final WriteContext writeContext) + throws WriteFailedException { + final byte isIpv6 = (byte) (isIpv6(vxlanGpe) + ? 1 + : 0); + final InetAddress local = InetAddresses.forString(getAddressString(vxlanGpe.getLocal())); + final InetAddress remote = InetAddresses.forString(getAddressString(vxlanGpe.getRemote())); + + int vni = vxlanGpe.getVni().getValue().intValue(); + byte protocol = (byte) vxlanGpe.getNextProtocol().getIntValue(); + int encapVrfId = vxlanGpe.getEncapVrfId().intValue(); + int decapVrfId = vxlanGpe.getDecapVrfId().intValue(); + + LOG.debug("Deleting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, vxlanGpe); + final CompletionStage VxlanGpeAddDelTunnelReplyCompletionStage = + getFutureJVpp() + .vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 0 /* is delete */, local.getAddress(), + remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); + getReplyForDelete(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + final int index = interfaceNamingContext.getIndex(swIfName, writeContext.getMappingContext()); + // Mark this interface as disabled to not include it in operational reads + // because VPP will keep the interface there + LOG.debug("Marking vxlan tunnel as disabled, id: {}, name: {}", index, swIfName); + interfaceDisableContext.disableInterface(index, writeContext.getMappingContext()); + // Remove interface from our interface naming context + interfaceNamingContext.removeName(swIfName, writeContext.getMappingContext()); + } + + private static VxlanGpeAddDelTunnel getVxlanGpeTunnelRequest(final byte isAdd, final byte[] local, + final byte[] remote, + final int vni, final byte protocol, + final int encapVrfId, final int decapVrfId, + final byte isIpv6) { + final VxlanGpeAddDelTunnel VxlanGpeAddDelTunnel = new VxlanGpeAddDelTunnel(); + VxlanGpeAddDelTunnel.isAdd = isAdd; + VxlanGpeAddDelTunnel.local = local; + VxlanGpeAddDelTunnel.remote = remote; + VxlanGpeAddDelTunnel.vni = vni; + VxlanGpeAddDelTunnel.protocol = protocol; + VxlanGpeAddDelTunnel.encapVrfId = encapVrfId; + VxlanGpeAddDelTunnel.decapVrfId = decapVrfId; + VxlanGpeAddDelTunnel.isIpv6 = isIpv6; + return VxlanGpeAddDelTunnel; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/IetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/IetfAclWriter.java new file mode 100644 index 000000000..d97bdee54 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/IetfAclWriter.java @@ -0,0 +1,106 @@ +/* + * 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.acl; + +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.Optional; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer customizer responsible for Access Control Lists management. Does not send any messages to VPP. All the config + * data are stored in HC and used when acl is assigned/unassigned to/from an interface. + * + * ACLs that are currently assigned to an interface cannot be updated/deleted. + */ +public class IetfAclWriter implements ListWriterCustomizer { + + public static final InstanceIdentifier ACL_ID = + InstanceIdentifier.create(AccessLists.class); + + private static final Logger LOG = LoggerFactory.getLogger(IetfAclWriter.class); + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Creating ACL: iid={} dataAfter={}", id, dataAfter); + + // no vpp call, just updates DataTree + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataBefore, + @Nonnull final Acl dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Updating ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter); + + if (isAssigned(dataAfter, writeContext)) { + throw new WriteFailedException(id, + String.format("Failed to update data at %s: acl %s is already assigned", id, dataAfter)); + } + + LOG.debug("Updating unassigned ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter); + + // no vpp call, just updates DataTree + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Deleting ACL: iid={} dataBefore={}", id, dataBefore); + + if (isAssigned(dataBefore, writeContext)) { + throw new WriteFailedException(id, + String.format("Failed to delete data at %s: acl %s is already assigned", id, dataBefore)); + } + + LOG.debug("Deleting unassigned ACL: iid={} dataBefore={}", id, dataBefore); + + // no vpp call, just updates DataTree + } + + private static boolean isAssigned(@Nonnull final Acl acl, + @Nonnull final WriteContext writeContext) { + final String aclName = acl.getAclName(); + final Class aclType = acl.getAclType(); + final Interfaces interfaces = writeContext.readAfter(InstanceIdentifier.create(Interfaces.class)).get(); + + return interfaces.getInterface().stream() + .map(i -> Optional.ofNullable(i.getAugmentation(VppInterfaceAugmentation.class)) + .map(aug -> aug.getIetfAcl()) + .map(ietfAcl -> ietfAcl.getIngress()) + .map(ingress -> ingress.getAccessLists()) + .map(accessLists -> accessLists.getAcl()) + ) + .flatMap(iacl -> iacl.isPresent() + ? iacl.get().stream() + : Stream.empty()) + .filter(assignedAcl -> aclName.equals(assignedAcl.getName()) && aclType.equals(assignedAcl.getType())) + .findFirst().isPresent(); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AbstractIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AbstractIetfAclWriter.java new file mode 100644 index 000000000..29e92ae2a --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AbstractIetfAclWriter.java @@ -0,0 +1,251 @@ +/* + * 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.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntries; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.AceType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.AceIpVersion; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractIetfAclWriter implements IetfAclWriter, JvppReplyConsumer, AclTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractIetfAclWriter.class); + protected static final int NOT_DEFINED = -1; + protected final FutureJVppCore jvpp; + + private Map> aceWriters = new HashMap<>(); + + public AbstractIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore) { + this.jvpp = Preconditions.checkNotNull(futureJVppCore, "futureJVppCore should not be null"); + aceWriters.put(AclType.ETH, new AceEthWriter()); + aceWriters.put(AclType.IP4, new AceIp4Writer()); + aceWriters.put(AclType.IP6, new AceIp6Writer()); + aceWriters.put(AclType.ETH_AND_IP, new AceIpAndEthWriter()); + } + + private static Stream aclToAceStream(@Nonnull final Acl assignedAcl, + @Nonnull final WriteContext writeContext) { + final String aclName = assignedAcl.getName(); + final Class aclType = assignedAcl.getType(); + + // ietf-acl updates are handled first, so we use writeContext.readAfter + final Optional + aclOptional = + writeContext.readAfter(io.fd.hc2vpp.v3po.interfaces.acl.IetfAclWriter.ACL_ID.child( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl.class, + new AclKey(aclName, aclType))); + checkArgument(aclOptional.isPresent(), "Acl lists not configured"); + final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl + acl = aclOptional.get(); + + final AccessListEntries accessListEntries = acl.getAccessListEntries(); + checkArgument(accessListEntries != null, "access list entries not configured"); + + return accessListEntries.getAce().stream(); + } + + protected void removeClassifyTables(@Nonnull final InstanceIdentifier id, @Nonnull final MappingEntry entry) + throws WriteFailedException { + removeClassifyTable(id, entry.getL2TableId()); + removeClassifyTable(id, entry.getIp4TableId()); + removeClassifyTable(id, entry.getIp6TableId()); + } + + private void removeClassifyTable(@Nonnull final InstanceIdentifier id, final int tableIndex) + throws WriteFailedException { + + if (tableIndex == -1) { + return; // classify table id is absent + } + final ClassifyAddDelTable request = new ClassifyAddDelTable(); + request.tableIndex = tableIndex; + final CompletionStage cs = jvpp.classifyAddDelTable(request); + getReplyForDelete(cs.toCompletableFuture(), id); + } + + protected static boolean appliesToIp4Path(final Ace ace) { + final AceType aceType = ace.getMatches().getAceType(); + final AclType aclType = AclType.fromAce(ace); + if (aclType == AclType.IP4) { + return true; + } + if (aclType == AclType.ETH) { + return true; // L2 only rules are possible for IP4 traffic + } + if (aclType == AclType.ETH_AND_IP && ((AceIpAndEth) aceType) + .getAceIpVersion() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv4) { + return true; + } + return false; + } + + protected static boolean appliesToIp6Path(final Ace ace) { + final AceType aceType = ace.getMatches().getAceType(); + final AclType aclType = AclType.fromAce(ace); + if (aclType == AclType.IP6) { + return true; + } + if (aclType == AclType.ETH) { + return true; // L2 only rules are possible for IP6 traffic + } + if (aclType == AclType.ETH_AND_IP && ((AceIpAndEth) aceType) + .getAceIpVersion() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv6) { + return true; + } + return false; + } + + protected static List getACEs(@Nonnull final List acls, @Nonnull final WriteContext writeContext, + final Predicate filter) { + return acls.stream().flatMap(acl -> aclToAceStream(acl, writeContext)).filter(filter) + .collect(Collectors.toList()); + } + + protected int writeAces(final InstanceIdentifier id, final List aces, + final AccessLists.DefaultAction defaultAction, final InterfaceMode mode, + final int vlanTags) throws WriteFailedException { + if (aces.isEmpty()) { + return NOT_DEFINED; + } + + int nextTableIndex = configureDefaultAction(id, defaultAction); + final ListIterator iterator = aces.listIterator(aces.size()); + while (iterator.hasPrevious()) { + final Ace ace = iterator.previous(); + LOG.trace("Processing ACE: {}", ace); + + final AceWriter aceWriter = + aceWriters.get(AclType.fromAce(ace)); + if (aceWriter == null) { + LOG.warn("AceProcessor for {} not registered. Skipping ACE.", ace.getClass()); + } else { + final AceType aceType = ace.getMatches().getAceType(); + final PacketHandling action = ace.getActions().getPacketHandling(); + final ClassifyAddDelTable ctRequest = aceWriter.createTable(aceType, mode, nextTableIndex, vlanTags); + nextTableIndex = createClassifyTable(id, ctRequest); + final List sessionRequests = + aceWriter.createSession(action, aceType, mode, nextTableIndex, vlanTags); + for (ClassifyAddDelSession csRequest : sessionRequests) { + createClassifySession(id, csRequest); + } + } + } + return nextTableIndex; + } + + private int configureDefaultAction(@Nonnull final InstanceIdentifier id, + final AccessLists.DefaultAction defaultAction) + throws WriteFailedException { + ClassifyAddDelTable ctRequest = createTable(-1); + if (AccessLists.DefaultAction.Permit.equals(defaultAction)) { + ctRequest.missNextIndex = -1; + } else { + ctRequest.missNextIndex = 0; + } + ctRequest.mask = new byte[16]; + ctRequest.skipNVectors = 0; + ctRequest.matchNVectors = 1; + return createClassifyTable(id, ctRequest); + } + + private int createClassifyTable(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyAddDelTable request) + throws WriteFailedException { + final CompletionStage cs = jvpp.classifyAddDelTable(request); + + final ClassifyAddDelTableReply reply = getReplyForWrite(cs.toCompletableFuture(), id); + return reply.newTableIndex; + } + + private void createClassifySession(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyAddDelSession request) + throws WriteFailedException { + final CompletionStage cs = jvpp.classifyAddDelSession(request); + + getReplyForWrite(cs.toCompletableFuture(), id); + } + + private enum AclType { + ETH, IP4, IP6, ETH_AND_IP; + + @Nonnull + private static AclType fromAce(final Ace ace) { + AclType result = null; + final AceType aceType; + try { + aceType = ace.getMatches().getAceType(); + if (aceType instanceof AceEth) { + result = ETH; + } else if (aceType instanceof AceIp) { + final AceIpVersion aceIpVersion = ((AceIp) aceType).getAceIpVersion(); + if (aceIpVersion == null) { + throw new IllegalArgumentException("Incomplete ACE (ip-version was not provided): " + ace); + } + if (aceIpVersion instanceof AceIpv4) { + result = IP4; + } else if (aceIpVersion instanceof AceIpv6) { + result = IP6; + } + } else if (aceType instanceof AceIpAndEth) { + result = ETH_AND_IP; + } + } catch (NullPointerException e) { + throw new IllegalArgumentException("Incomplete ACE: " + ace, e); + } + if (result == null) { + throw new IllegalArgumentException(String.format("Not supported ace type %s", aceType)); + } + return result; + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriter.java new file mode 100644 index 000000000..67351e0c6 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriter.java @@ -0,0 +1,85 @@ +/* + * 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.acl.common; + +import com.google.common.annotations.VisibleForTesting; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class AceEthWriter implements AceWriter, AclTranslator, L2AclTranslator { + + @VisibleForTesting + static final int MATCH_N_VECTORS = 1; + private static final Logger LOG = LoggerFactory.getLogger(AceEthWriter.class); + + @Override + public ClassifyAddDelTable createTable(@Nonnull final AceEth aceEth, + @Nullable final InterfaceMode mode, + final int nextTableIndex, + final int vlanTags) { + final ClassifyAddDelTable request = createTable(nextTableIndex); + + request.mask = new byte[16]; + boolean aceIsEmpty = + destinationMacAddressMask(aceEth.getDestinationMacAddressMask(), aceEth.getDestinationMacAddress(), + request); + aceIsEmpty &= + sourceMacAddressMask(aceEth.getSourceMacAddressMask(), aceEth.getSourceMacAddress(), request); + + if (aceIsEmpty) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceEth.toString())); + } + + request.skipNVectors = 0; + request.matchNVectors = MATCH_N_VECTORS; + + LOG.debug("ACE rule={} translated to table={}.", aceEth, request); + return request; + } + + @Override + public List createSession(@Nonnull final PacketHandling action, + @Nonnull final AceEth aceEth, + @Nullable final InterfaceMode mode, + final int tableIndex, + final int vlanTags) { + final ClassifyAddDelSession request = createSession(action, tableIndex); + + request.match = new byte[16]; + boolean noMatch = destinationMacAddressMatch(aceEth.getDestinationMacAddress(), request); + noMatch &= sourceMacAddressMatch(aceEth.getSourceMacAddress(), request); + + if (noMatch) { + throw new IllegalArgumentException( + String.format("Ace %s does not define neither source nor destination MAC address", + aceEth.toString())); + } + + LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceEth, request); + return Collections.singletonList(request); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4Writer.java new file mode 100644 index 000000000..78ed33aa4 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4Writer.java @@ -0,0 +1,94 @@ +/* + * 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.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.annotations.VisibleForTesting; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class AceIp4Writer implements AceWriter, AclTranslator, Ip4AclTranslator { + + @VisibleForTesting + static final int MATCH_N_VECTORS = 3; // number of 16B vectors + private static final int TABLE_MASK_LENGTH = 48; + private static final Logger LOG = LoggerFactory.getLogger(AceIp4Writer.class); + + @Override + public ClassifyAddDelTable createTable(@Nonnull final AceIp aceIp, + @Nullable final InterfaceMode mode, + final int nextTableIndex, + final int vlanTags) { + checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp); + final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion(); + + final int numberOfSessions = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()).size(); + final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); + request.skipNVectors = 0; // match entire L2 and L3 header + request.matchNVectors = MATCH_N_VECTORS; + request.mask = new byte[TABLE_MASK_LENGTH]; + + final int baseOffset = getVlanTagsLen(vlanTags); + boolean aceIsEmpty = ip4Mask(baseOffset, mode, aceIp, ipVersion, request); + if (aceIsEmpty) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceIp.toString())); + } + + LOG.debug("ACE rule={} translated to table={}.", aceIp, request); + return request; + } + + @Override + public List createSession(@Nonnull final PacketHandling action, + @Nonnull final AceIp aceIp, + @Nullable final InterfaceMode mode, + final int tableIndex, + final int vlanTags) { + checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp); + final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion(); + + final List portPairs = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()); + final List requests = new ArrayList<>(portPairs.size()); + for (final PortPair pair : portPairs) { + final ClassifyAddDelSession request = createSession(action, tableIndex); + request.match = new byte[TABLE_MASK_LENGTH]; + + final int baseOffset = getVlanTagsLen(vlanTags); + boolean noMatch = ip4Match(baseOffset, mode, aceIp, ipVersion, pair.getSrc(), pair.getDst(), request); + if (noMatch) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceIp.toString())); + } + + LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request); + requests.add(request); + } + return requests; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6Writer.java new file mode 100644 index 000000000..d7cbb0009 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6Writer.java @@ -0,0 +1,99 @@ +/* + * 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.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class AceIp6Writer implements AceWriter, AclTranslator, Ip6AclTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(AceIp6Writer.class); + + @Override + public ClassifyAddDelTable createTable(@Nonnull final AceIp aceIp, + @Nullable final InterfaceMode mode, + final int nextTableIndex, + final int vlanTags) { + checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp); + final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion(); + + final int numberOfSessions = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()).size(); + final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); + request.skipNVectors = 0; // match entire L2 and L3 header + request.mask = new byte[getTableMaskLength(vlanTags)]; + request.matchNVectors = request.mask.length/16; + + final int baseOffset = getVlanTagsLen(vlanTags); + boolean aceIsEmpty = ip6Mask(baseOffset, mode, aceIp, ipVersion, request); + if (aceIsEmpty) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceIp.toString())); + } + + LOG.debug("ACE rule={} translated to table={}.", aceIp, request); + return request; + } + + private static int getTableMaskLength(final int vlanTags) { + if (vlanTags == 2) { + return 80; + } else { + return 64; + } + } + + @Override + public List createSession(@Nonnull final PacketHandling action, + @Nonnull final AceIp aceIp, + @Nullable final InterfaceMode mode, + final int tableIndex, + final int vlanTags) { + checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp); + final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion(); + final List portPairs = + PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()); + + final List requests = new ArrayList<>(portPairs.size()); + for (final PortPair pair : portPairs) { + final ClassifyAddDelSession request = createSession(action, tableIndex); + request.match = new byte[getTableMaskLength(vlanTags)]; + + final int baseOffset = getVlanTagsLen(vlanTags); + boolean noMatch = ip6Match(baseOffset, mode, aceIp, ipVersion, pair.getSrc(), pair.getDst(), request); + if (noMatch) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", aceIp.toString())); + } + + LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request); + requests.add(request); + } + return requests; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriter.java new file mode 100644 index 000000000..164493cc5 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriter.java @@ -0,0 +1,129 @@ +/* + * 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.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.AceIpVersion; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv6; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class AceIpAndEthWriter + implements AceWriter, AclTranslator, L2AclTranslator, Ip4AclTranslator, Ip6AclTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(AceIpAndEthWriter.class); + + private static int maskLength(@Nonnull final AceIpAndEth ace, final int vlanTags) { + if (ace.getAceIpVersion() != null) { + if (ace.getAceIpVersion() instanceof AceIpv4) { + return 48; + } else { + return vlanTags == 2 + ? 80 + : 64; + } + } + return 16; + } + + @Override + public ClassifyAddDelTable createTable(@Nonnull final AceIpAndEth ace, @Nullable final InterfaceMode mode, + final int nextTableIndex, final int vlanTags) { + final int numberOfSessions = PortPair.fromRange(ace.getSourcePortRange(), ace.getDestinationPortRange()).size(); + final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); + final int maskLength = maskLength(ace, vlanTags); + request.mask = new byte[maskLength]; + request.skipNVectors = 0; + request.matchNVectors = maskLength / 16; + + boolean aceIsEmpty = + destinationMacAddressMask(ace.getDestinationMacAddressMask(), ace.getDestinationMacAddress(), request); + aceIsEmpty &= sourceMacAddressMask(ace.getSourceMacAddressMask(), ace.getSourceMacAddress(), request); + + // if we use classifier API, we need to know ip version (fields common for ip4 and ip6 have different offsets): + final AceIpVersion aceIpVersion = ace.getAceIpVersion(); + checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion"); + + final int baseOffset = getVlanTagsLen(vlanTags); + if (aceIpVersion instanceof AceIpv4) { + final AceIpv4 ipVersion = (AceIpv4) aceIpVersion; + aceIsEmpty &= ip4Mask(baseOffset, mode, ace, ipVersion, request); + } else if (aceIpVersion instanceof AceIpv6) { + final AceIpv6 ipVersion = (AceIpv6) aceIpVersion; + aceIsEmpty &= ip6Mask(baseOffset, mode, ace, ipVersion, request); + } else { + throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion)); + } + + if (aceIsEmpty) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", ace.toString())); + } + + LOG.debug("ACE rule={} translated to table={}.", ace, request); + return request; + } + + @Override + public List createSession(@Nonnull final PacketHandling action, + @Nonnull final AceIpAndEth ace, + @Nullable final InterfaceMode mode, final int tableIndex, + final int vlanTags) { + final List portPairs = PortPair.fromRange(ace.getSourcePortRange(), ace.getDestinationPortRange()); + final List requests = new ArrayList<>(portPairs.size()); + for (final PortPair pair : portPairs) { + final ClassifyAddDelSession request = createSession(action, tableIndex); + request.match = new byte[maskLength(ace, vlanTags)]; + + boolean noMatch = destinationMacAddressMatch(ace.getDestinationMacAddress(), request); + noMatch &= sourceMacAddressMatch(ace.getSourceMacAddress(), request); + + final AceIpVersion aceIpVersion = ace.getAceIpVersion(); + checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion"); + + final int baseOffset = getVlanTagsLen(vlanTags); + if (aceIpVersion instanceof AceIpv4) { + final AceIpv4 ipVersion = (AceIpv4) aceIpVersion; + noMatch &= ip4Match(baseOffset, mode, ace, ipVersion, pair.getSrc(), pair.getDst(), request); + } else if (aceIpVersion instanceof AceIpv6) { + final AceIpv6 ipVersion = (AceIpv6) aceIpVersion; + noMatch &= ip6Match(baseOffset, mode, ace, ipVersion, pair.getSrc(), pair.getDst(), request); + } else { + throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion)); + } + + if (noMatch) { + throw new IllegalArgumentException( + String.format("Ace %s does not define packet field match values", ace.toString())); + } + LOG.debug("ACE action={}, rule={} translated to session={}.", action, ace, request); + requests.add(request); + } + return requests; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceWriter.java new file mode 100644 index 000000000..75a10e40f --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceWriter.java @@ -0,0 +1,54 @@ +/* + * 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.acl.common; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.AceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; + +/** + * Writer responsible for translation of ietf-acl model ACEs to VPP's classify tables and sessions. + * + * @param type of access control list entry + */ +interface AceWriter { + /** + * @param ace access list entry + * @param mode interface mode (L2/L3) + * @param nextTableIndex index of the next classify table in chain + * @param vlanTags number of vlan tags + */ + @Nonnull + ClassifyAddDelTable createTable(@Nonnull final T ace, @Nullable final InterfaceMode mode, final int nextTableIndex, + final int vlanTags); + + /** + * @param action to be taken when packet does match the specified ace + * @param ace access list entry + * @param mode interface mode (L2/L3) + * @param tableIndex index of corresponding classify table + * @param vlanTags number of vlan tags + */ + @Nonnull + List createSession(@Nonnull final PacketHandling action, @Nonnull T ace, + @Nullable final InterfaceMode mode, final int tableIndex, final int vlanTags); +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManager.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManager.java new file mode 100644 index 000000000..0728944f2 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManager.java @@ -0,0 +1,53 @@ +/* + * 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.acl.common; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; + +/** + * Manages interface metadata for ietf-acl model. + */ +public interface AclTableContextManager { + + /** + * Obtains mapping entry for given interface. + * + * @param index interface index + * @param mappingContext mapping context providing context data for current transaction + * @return ietf-acl metadata for given interface + */ + Optional getEntry(final int index, @Nonnull final MappingContext mappingContext); + + /** + * Adds mapping entry. + * + * @param entry to be added + * @param mappingContext mapping context providing context data for current transaction + */ + void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext); + + /** + * Removes entry for given interface (if present). + * + * @param index interface index + * @param mappingContext mapping context providing context data for current transaction + */ + void removeEntry(final int index, @Nonnull final MappingContext mappingContext); +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImpl.java new file mode 100644 index 000000000..659244fda --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImpl.java @@ -0,0 +1,68 @@ +/* + * 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.acl.common; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.ThreadSafe; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.AclMappingEntryCtxAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.AclMappingEntryContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +@ThreadSafe +public class AclTableContextManagerImpl implements AclTableContextManager { + + private MappingTable.Direction direction; + + public AclTableContextManagerImpl(@Nonnull final MappingTable.Direction direction) { + this.direction = checkNotNull(direction, "direction should not be null"); + } + + @Nonnull + @Override + public synchronized Optional getEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { + return mappingContext.read(getId(swIfIndex)); + } + + @Override + public synchronized void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext) { + mappingContext.put(getId(entry.getIndex()), entry); + } + + @Override + public synchronized void removeEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { + mappingContext.delete(getId(swIfIndex)); + } + + @VisibleForTesting + protected InstanceIdentifier getId(final int index) { + return InstanceIdentifier.create(Contexts.class) + .augmentation(AclMappingEntryCtxAugmentation.class) + .child(AclMappingEntryContext.class) + .child(MappingTable.class, new MappingTableKey(direction)) + .child(MappingEntry.class, new MappingEntryKey(index)); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTranslator.java new file mode 100644 index 000000000..e4291122d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTranslator.java @@ -0,0 +1,74 @@ +/* + * 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.acl.common; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit; + +/** + * Utility that helps translating of ietf-acl model ACEs to VPP's classify tables and sessions. + */ +interface AclTranslator { + int TABLE_MEM_SIZE = 8 * 1024; + int VLAN_TAG_LEN = 4; + + default ClassifyAddDelTable createTable(final int nextTableIndex) { + return createTable(nextTableIndex, 1); + } + + default ClassifyAddDelTable createTable(final int nextTableIndex, @Nonnegative final int numberOfSessions) { + final ClassifyAddDelTable request = new ClassifyAddDelTable(); + request.isAdd = 1; + request.tableIndex = -1; // value not present + request.nbuckets = numberOfSessions; + request.nextTableIndex = nextTableIndex; + + + // TODO: HONEYCOMB-181 minimise memory used by classify tables (we create a lot of them to make ietf-acl model + // mapping more convenient): + // according to https://wiki.fd.io/view/VPP/Introduction_To_N-tuple_Classifiers#Creating_a_classifier_table, + // classify table needs 16*(1 + match_n_vectors) bytes, but this does not quite work, + // so setting 8K +1k*numberOfSessions for now + checkArgument(numberOfSessions>0, "negative numberOfSessions %s", numberOfSessions); + request.memorySize = TABLE_MEM_SIZE+1024*(numberOfSessions-1); + request.missNextIndex = -1; // value not set, but anyway it is ignored for tables in chain + return request; + } + + default ClassifyAddDelSession createSession(@Nonnull final PacketHandling action, final int tableIndex) { + final ClassifyAddDelSession request = new ClassifyAddDelSession(); + request.isAdd = 1; + request.tableIndex = tableIndex; + request.opaqueIndex = ~0; // value not used + + if (action instanceof Permit) { + request.hitNextIndex = -1; + } // deny (0) is default value + + return request; + } + + default int getVlanTagsLen(final int vlanTags) { + return vlanTags * VLAN_TAG_LEN; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/IetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/IetfAclWriter.java new file mode 100644 index 000000000..df0b65c2e --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/IetfAclWriter.java @@ -0,0 +1,47 @@ +/* + * 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.acl.common; + +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.List; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public interface IetfAclWriter { + default void write(@Nonnull final InstanceIdentifier id, final int ifIndex, @Nonnull final List acls, + final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + write(id, ifIndex, acls, defaultAction, mode, writeContext, 0, mappingContext); + } + + void write(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final List acls, + final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException; + + void deleteAcl(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final MappingContext mappingContext) + throws WriteFailedException; +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip4AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip4AclTranslator.java new file mode 100644 index 000000000..c1bad0735 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip4AclTranslator.java @@ -0,0 +1,149 @@ +/* + * 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.acl.common; + +import com.google.common.primitives.Ints; +import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpHeaderFields; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv4HeaderFields; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; + +interface Ip4AclTranslator extends Ipv4Translator { + int ETHER_TYPE_OFFSET = 12; // first 14 bytes represent L2 header (2x6) + int DSCP_OFFSET = 15; + int DSCP_MASK = 0xfc; + + int IP_PROTOCOL_OFFSET = ETHER_TYPE_OFFSET + 11; + int IP_PROTOCOL_MASK = 0xff; + + int IP4_LEN = 4; + int IP4_MASK_BIT_LENGTH = 32; + int SRC_IP_OFFSET = ETHER_TYPE_OFFSET + 14; + int DST_IP_OFFSET = SRC_IP_OFFSET + IP4_LEN; + int SRC_PORT_OFFSET = DST_IP_OFFSET + IP4_LEN; + int DST_PORT_OFFSET = SRC_PORT_OFFSET + 2; + + default boolean ip4Mask(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, + final AclIpv4HeaderFields ip4, final ClassifyAddDelTable request) { + boolean aceIsEmpty = true; + if (InterfaceMode.L2.equals(mode)) { + // in L2 mode we need to match ether type + request.mask[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0xff; + request.mask[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xff; + } + if (header.getDscp() != null) { + aceIsEmpty = false; + request.mask[baseOffset + DSCP_OFFSET] = (byte) DSCP_MASK; // first 6 bits + } + if (header.getProtocol() != null) { // Internet Protocol number + aceIsEmpty = false; + request.mask[baseOffset + IP_PROTOCOL_OFFSET] = (byte) IP_PROTOCOL_MASK; + } + if (header.getSourcePortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + aceIsEmpty = false; + request.mask[baseOffset + SRC_PORT_OFFSET] = (byte) 0xff; + request.mask[baseOffset + SRC_PORT_OFFSET + 1] = (byte) 0xff; + } + if (header.getDestinationPortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + aceIsEmpty = false; + request.mask[baseOffset + DST_PORT_OFFSET] = (byte) 0xff; + request.mask[baseOffset + DST_PORT_OFFSET + 1] = (byte) 0xff; + } + if (ip4.getSourceIpv4Network() != null) { + aceIsEmpty = false; + System.arraycopy(Impl.toByteMask(ip4.getSourceIpv4Network()), 0, request.mask, + baseOffset + SRC_IP_OFFSET, IP4_LEN); + } + if (ip4.getDestinationIpv4Network() != null) { + aceIsEmpty = false; + System.arraycopy(Impl.toByteMask(ip4.getDestinationIpv4Network()), 0, request.mask, + baseOffset + DST_IP_OFFSET, IP4_LEN); + } + return aceIsEmpty; + } + + default boolean ip4Match(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, + final AclIpv4HeaderFields ip4, final Integer srcPort, + final Integer dstPort, final ClassifyAddDelSession request) { + boolean noMatch = true; + if (InterfaceMode.L2.equals(mode)) { + // match IP4 etherType (0x0800) + request.match[baseOffset + ETHER_TYPE_OFFSET] = 0x08; + request.match[baseOffset + ETHER_TYPE_OFFSET + 1] = 0x00; + } + if (header.getDscp() != null) { + noMatch = false; + request.match[baseOffset + DSCP_OFFSET] = (byte) (DSCP_MASK & (header.getDscp().getValue() << 2)); + } + if (header.getProtocol() != null) { // Internet Protocol number + noMatch = false; + request.match[baseOffset + IP_PROTOCOL_OFFSET] = (byte) (IP_PROTOCOL_MASK & header.getProtocol()); + } + if (srcPort != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + noMatch = false; + request.match[baseOffset + SRC_PORT_OFFSET] = (byte) (0xff & srcPort >> 8); + request.match[baseOffset + SRC_PORT_OFFSET + 1] = (byte) (0xff & srcPort); + } + if (header.getDestinationPortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + noMatch = false; + request.match[baseOffset + DST_PORT_OFFSET] = (byte) (0xff & dstPort >> 8); + request.match[baseOffset + DST_PORT_OFFSET + 1] = (byte) (0xff & dstPort); + } + if (ip4.getSourceIpv4Network() != null) { + noMatch = false; + System.arraycopy(Impl.toMatchValue(ip4.getSourceIpv4Network()), 0, request.match, + baseOffset + SRC_IP_OFFSET, IP4_LEN); + + } + if (ip4.getDestinationIpv4Network() != null) { + noMatch = false; + System.arraycopy(Impl.toMatchValue(ip4.getDestinationIpv4Network()), 0, request.match, + baseOffset + DST_IP_OFFSET, IP4_LEN); + + } + return noMatch; + } + + class Impl { + private static byte[] toByteMask(final int prefixLength) { + final long mask = ((1L << prefixLength) - 1) << (IP4_MASK_BIT_LENGTH - prefixLength); + return Ints.toByteArray((int) mask); + } + + private static byte[] toByteMask(final Ipv4Prefix ipv4Prefix) { + final int prefixLength = Byte.valueOf(ipv4Prefix.getValue().split("/")[1]); + return toByteMask(prefixLength); + } + + private static byte[] toMatchValue(final Ipv4Prefix ipv4Prefix) { + final String[] split = ipv4Prefix.getValue().split("/"); + final byte[] addressBytes = Ipv4Translator.INSTANCE.ipv4AddressNoZoneToArray(split[0]); + final byte[] mask = Impl.toByteMask(Byte.valueOf(split[1])); + for (int i = 0; i < addressBytes.length; ++i) { + addressBytes[i] &= mask[i]; + } + return addressBytes; + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip6AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip6AclTranslator.java new file mode 100644 index 000000000..ec9bebe7e --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/Ip6AclTranslator.java @@ -0,0 +1,182 @@ +/* + * 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.acl.common; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.BitSet; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpHeaderFields; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv6HeaderFields; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; + +interface Ip6AclTranslator { + + int ETHER_TYPE_OFFSET = 12; // first 14 bytes represent L2 header (2x6) + int IP_VERSION_OFFSET = ETHER_TYPE_OFFSET + 2; + int DSCP_MASK1 = 0x0f; + int DSCP_MASK2 = 0xc0; + int IP_PROTOCOL_OFFSET = IP_VERSION_OFFSET + 6; + int IP_PROTOCOL_MASK = 0xff; + int IP6_LEN = 16; + int SRC_IP_OFFSET = IP_VERSION_OFFSET + 8; + int DST_IP_OFFSET = SRC_IP_OFFSET + IP6_LEN; + int SRC_PORT_OFFSET = DST_IP_OFFSET + IP6_LEN; + int DST_PORT_OFFSET = SRC_PORT_OFFSET + 2; + + default boolean ip6Mask(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, + final AclIpv6HeaderFields ip6, final ClassifyAddDelTable request) { + boolean aceIsEmpty = true; + if (InterfaceMode.L2.equals(mode)) { + // in L2 mode we need to match ether type + request.mask[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0xff; + request.mask[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xff; + } + if (header.getDscp() != null) { + aceIsEmpty = false; + // DCSP (bits 4-9 of IP6 header) + request.mask[baseOffset + IP_VERSION_OFFSET] |= DSCP_MASK1; + request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= DSCP_MASK2; + } + if (header.getProtocol() != null) { // Internet Protocol number + aceIsEmpty = false; + request.mask[baseOffset + IP_PROTOCOL_OFFSET] = (byte) IP_PROTOCOL_MASK; + } + if (ip6.getFlowLabel() != null) { + aceIsEmpty = false; + // bits 12-31 + request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) 0x0f; + request.mask[baseOffset + IP_VERSION_OFFSET + 2] = (byte) 0xff; + request.mask[baseOffset + IP_VERSION_OFFSET + 3] = (byte) 0xff; + } + if (header.getSourcePortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + aceIsEmpty = false; + request.mask[baseOffset + SRC_PORT_OFFSET] = (byte) 0xff; + request.mask[baseOffset + SRC_PORT_OFFSET + 1] = (byte) 0xff; + } + if (header.getDestinationPortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + aceIsEmpty = false; + request.mask[baseOffset + DST_PORT_OFFSET] = (byte) 0xff; + request.mask[baseOffset + DST_PORT_OFFSET + 1] = (byte) 0xff; + } + if (ip6.getSourceIpv6Network() != null) { + aceIsEmpty = false; + final byte[] mask = Impl.toByteMask(ip6.getSourceIpv6Network()); + System.arraycopy(mask, 0, request.mask, baseOffset + SRC_IP_OFFSET, mask.length); + } + if (ip6.getDestinationIpv6Network() != null) { + aceIsEmpty = false; + final byte[] mask = Impl.toByteMask(ip6.getDestinationIpv6Network()); + System.arraycopy(mask, 0, request.mask, baseOffset + DST_IP_OFFSET, mask.length); + } + return aceIsEmpty; + } + + default boolean ip6Match(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, + final AclIpv6HeaderFields ip6, final Integer srcPort, final Integer dstPort, final ClassifyAddDelSession request) { + boolean noMatch = true; + if (InterfaceMode.L2.equals(mode)) { + // match IP6 etherType (0x86dd) + request.match[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0x86; + request.match[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xdd; + } + if (header.getDscp() != null) { + noMatch = false; + final int dcsp = header.getDscp().getValue(); + // set bits 4-9 of IP6 header: + request.match[baseOffset + IP_VERSION_OFFSET] |= (byte) (DSCP_MASK1 & (dcsp >> 2)); + request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (DSCP_MASK2 & (dcsp << 6)); + } + if (header.getProtocol() != null) { // Internet Protocol number + noMatch = false; + request.match[baseOffset + IP_PROTOCOL_OFFSET] = (byte) (IP_PROTOCOL_MASK & header.getProtocol()); + } + if (ip6.getFlowLabel() != null) { + noMatch = false; + final int flowLabel = ip6.getFlowLabel().getValue().intValue(); + // bits 12-31 + request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (0x0f & (flowLabel >> 16)); + request.match[baseOffset + IP_VERSION_OFFSET + 2] = (byte) (0xff & (flowLabel >> 8)); + request.match[baseOffset + IP_VERSION_OFFSET + 3] = (byte) (0xff & flowLabel); + } + if (header.getSourcePortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + noMatch = false; + request.match[baseOffset + SRC_PORT_OFFSET] = (byte) (0xff & srcPort >> 8); + request.match[baseOffset + SRC_PORT_OFFSET + 1] = (byte) (0xff & srcPort); + } + if (header.getDestinationPortRange() != null) { + // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present + noMatch = false; + request.match[baseOffset + DST_PORT_OFFSET] = (byte) (0xff & dstPort >> 8); + request.match[baseOffset + DST_PORT_OFFSET + 1] = (byte) (0xff & dstPort); + } + if (ip6.getSourceIpv6Network() != null) { + noMatch = false; + final byte[] match = Impl.toMatchValue(ip6.getSourceIpv6Network()); + System.arraycopy(match, 0, request.match, baseOffset + SRC_IP_OFFSET, IP6_LEN); + } + if (ip6.getDestinationIpv6Network() != null) { + noMatch = false; + final byte[] match = Impl.toMatchValue(ip6.getDestinationIpv6Network()); + System.arraycopy(match, 0, request.match, baseOffset + DST_IP_OFFSET, IP6_LEN); + } + return noMatch; + } + + class Impl { + private static final int IP6_MASK_BIT_LENGTH = 128; + + private static byte[] toByteMask(final int prefixLength) { + final BitSet mask = new BitSet(IP6_MASK_BIT_LENGTH); + mask.set(0, prefixLength, true); + if (prefixLength < IP6_MASK_BIT_LENGTH) { + mask.set(prefixLength, IP6_MASK_BIT_LENGTH, false); + } + return mask.toByteArray(); + } + + private static byte[] toByteMask(final Ipv6Prefix ipv6Prefix) { + final int prefixLength = Short.valueOf(ipv6Prefix.getValue().split("/")[1]); + return toByteMask(prefixLength); + } + + private static byte[] toMatchValue(final Ipv6Prefix ipv6Prefix) { + final String[] split = ipv6Prefix.getValue().split("/"); + final byte[] addressBytes; + try { + addressBytes = InetAddress.getByName(split[0]).getAddress(); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Invalid IP6 address", e); + } + final byte[] mask = toByteMask(Short.valueOf(split[1])); + int pos = 0; + for (; pos < mask.length; ++pos) { + addressBytes[pos] &= mask[pos]; + } + // mask can be shorter that address, so we need to clear rest of the address: + for (; pos < addressBytes.length; ++pos) { + addressBytes[pos] = 0; + } + return addressBytes; + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/L2AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/L2AclTranslator.java new file mode 100644 index 000000000..5a6807bba --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/L2AclTranslator.java @@ -0,0 +1,90 @@ +/* + * 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.acl.common; + +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.util.List; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; + +interface L2AclTranslator extends MacTranslator { + + default boolean destinationMacAddressMask(final MacAddress dstMask, final MacAddress dstAddress, + final ClassifyAddDelTable request) { + // destination-mac-address or destination-mac-address-mask is present => + // ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00:00:00 + if (dstMask != null) { + final List parts = COLON_SPLITTER.splitToList(dstMask.getValue()); + int i = 0; + for (String part : parts) { + request.mask[i++] = parseHexByte(part); + } + return false; + } else if (dstAddress != null) { + for (int i = 0; i < 6; ++i) { + request.mask[i] = (byte) 0xff; + } + return false; + } + return true; + } + + default boolean sourceMacAddressMask(final MacAddress srcMask, final MacAddress srcAddress, + final ClassifyAddDelTable request) { + // source-mac-address or source-mac-address-mask => + // 00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:00:00:00:00 + if (srcMask != null) { + final List parts = COLON_SPLITTER.splitToList(srcMask.getValue()); + int i = 6; + for (String part : parts) { + request.mask[i++] = parseHexByte(part); + } + return false; + } else if (srcAddress != null) { + for (int i = 6; i < 12; ++i) { + request.mask[i] = (byte) 0xff; + } + return false; + } + return true; + } + + default boolean destinationMacAddressMatch(final MacAddress dstAddress, final ClassifyAddDelSession request) { + if (dstAddress != null) { + final List parts = COLON_SPLITTER.splitToList(dstAddress.getValue()); + int i = 0; + for (String part : parts) { + request.match[i++] = parseHexByte(part); + } + return false; + } + return true; + } + + default boolean sourceMacAddressMatch(final MacAddress srcAddress, final ClassifyAddDelSession request) { + if (srcAddress != null) { + final List parts = COLON_SPLITTER.splitToList(srcAddress.getValue()); + int i = 6; + for (String part : parts) { + request.match[i++] = parseHexByte(part); + } + return false; + } + return true; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPair.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPair.java new file mode 100644 index 000000000..1630f58fd --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPair.java @@ -0,0 +1,126 @@ +/* + * 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.acl.common; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.BiFunction; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange; + +/** + * Utility that produces cartesian product out of src and dst port ranges (used to translate ranges into + * list of classify sessions). + */ +final class PortPair { + private final Integer src; + private final Integer dst; + + PortPair(@Nullable final Integer src, @Nullable final Integer dst) { + this.src = src; + this.dst = dst; + } + + Integer getSrc() { + return src; + } + + Integer getDst() { + return dst; + } + + @Override + public String toString() { + return "(" + src + "," + dst + ")"; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final PortPair that = (PortPair) o; + if (!Objects.equals(src, that.src)) { + return false; + } + if (!Objects.equals(dst, that.dst)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return Objects.hash(src, dst); + } + + static List fromRange(final SourcePortRange srcRange, + final DestinationPortRange dstRange) { + final List result = new ArrayList<>(); + if (srcRange == null && dstRange == null) { + result.add(new PortPair(null, null)); + } else if (srcRange != null && dstRange == null) { + processSingleRange(result, srcRange.getLowerPort(), srcRange.getUpperPort(), PortPair::new); + } else if (srcRange == null && dstRange != null) { + processSingleRange(result, dstRange.getLowerPort(), dstRange.getUpperPort(), + (dst, src) -> new PortPair(src, dst)); + } else { + processDoubleRange(result, srcRange, dstRange); + } + return result; + } + + private static void processSingleRange(final List result, + final PortNumber lowerPort, + final PortNumber upperPort, + final BiFunction f) { + int low = lowerPort.getValue(); // mandatory + int hi = low; + if (upperPort != null) { + hi = upperPort.getValue(); + } + for (; low <= hi; ++low) { + result.add(f.apply(low, null)); + } + } + + private static void processDoubleRange(final List result, final SourcePortRange srcRange, + final DestinationPortRange dstRange) { + int srcL = srcRange.getLowerPort().getValue(); + int srcH = srcL; + if (srcRange.getUpperPort() != null) { + srcH = srcRange.getUpperPort().getValue(); + } + int dstL = dstRange.getLowerPort().getValue(); + int dstH = dstL; + if (dstRange.getUpperPort() != null) { + dstH = dstRange.getUpperPort().getValue(); + } + for (int i=srcL; i <= srcH; ++i) { + for (int j=dstL; j <= dstH; ++j) { + result.add(new PortPair(i, j)); + } + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriter.java new file mode 100644 index 000000000..adb19e360 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriter.java @@ -0,0 +1,120 @@ +/* + * 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.acl.egress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.hc2vpp.v3po.interfaces.acl.common.AbstractIetfAclWriter; +import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2Tables; +import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2TablesReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Matches; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class EgressIetfAclWriter extends AbstractIetfAclWriter { + private final AclTableContextManager aclCtx; + + public EgressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { + super(futureJVppCore); + this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); + } + + @Override + public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); + checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); + final MappingEntry entry = optional.get(); + unassignClassifyTables(id, swIfIndex); + removeClassifyTables(id, entry); + aclCtx.removeEntry(swIfIndex, mappingContext); + } + + private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, final int swIfIndex) + throws WriteFailedException { + final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); + request.swIfIndex = swIfIndex; + request.ip4TableIndex = NOT_DEFINED; + request.ip6TableIndex = NOT_DEFINED; + request.otherTableIndex = NOT_DEFINED; + request.isInput = 0; // egress + final CompletionStage cs = jvpp.classifySetInterfaceL2Tables(request); + getReplyForDelete(cs.toCompletableFuture(), id); + } + + @Override + public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, + @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); + checkArgument(InterfaceMode.L2.equals(mode), "Writing egress Acls is supported only in L2 mode"); + + final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); + request.isInput = 0; // egress + request.swIfIndex = swIfIndex; + + // applied to packets according to their ether type + final List ip4Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp4Path)); + request.ip4TableIndex = writeAces(id, ip4Aces, defaultAction, mode, numberOfTags); + final List ip6Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp6Path)); + request.ip6TableIndex = writeAces(id, ip6Aces, defaultAction, mode, numberOfTags); + final List aces = getACEs(acls, writeContext, EgressIetfAclWriter::isNotIpRule); + request.otherTableIndex = writeAces(id, aces, defaultAction, mode, numberOfTags); + + final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) + .setIp4TableId(request.ip4TableIndex) + .setIp6TableId(request.ip6TableIndex) + .setL2TableId(request.otherTableIndex) + .build(); + aclCtx.addEntry(entry, mappingContext); + + try { + getReplyForWrite(jvpp.classifySetInterfaceL2Tables(request).toCompletableFuture(), id); + } catch (WriteFailedException e) { + removeClassifyTables(id, entry); + throw e; + } + } + + private static boolean isNotIpRule(final Ace ace) { + final Matches matches = ace.getMatches(); + checkArgument(matches != null, "Incomplete ACE: %s", ace); + return matches.getAceType() instanceof AceEth; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizer.java new file mode 100644 index 000000000..3cef7a697 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizer.java @@ -0,0 +1,85 @@ +/* + * 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.acl.egress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.v3po.interfaces.acl.common.IetfAclWriter; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.v3po.rev161214.interfaces._interface.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IetfAclCustomizer implements WriterCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(IetfAclCustomizer.class); + private final IetfAclWriter aclWriter; + private final NamingContext interfaceContext; + + public IetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { + this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + LOG.debug("Adding egress ACLs for interface={}(id={}): {}", ifName, ifIndex, dataAfter); + + final AccessLists accessLists = dataAfter.getAccessLists(); + checkArgument(accessLists != null && accessLists.getAcl() != null, + "ietf-acl container does not define acl list"); + + if (!InterfaceMode.L2.equals(accessLists.getMode())) { + LOG.debug("Writing egress Acls is supported only in L2 mode. Ignoring config: {}", dataAfter); + return; + } + + aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, + @Nonnull final Egress dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("ACLs update: removing previously configured ACLs"); + deleteCurrentAttributes(id, dataBefore, writeContext); + LOG.debug("ACLs update: adding updated ACLs"); + writeCurrentAttributes(id, dataAfter, writeContext); + LOG.debug("ACLs update was successful"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); + aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java new file mode 100644 index 000000000..3ea40436b --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java @@ -0,0 +1,105 @@ +/* + * 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.acl.egress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getNumberOfTags; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.v3po.interfaces.acl.common.IetfAclWriter; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIetfAclCustomizer.class); + private final IetfAclWriter aclWriter; + private final NamingContext interfaceContext; + + public SubInterfaceIetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { + this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + return SubInterfaceUtils + .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + LOG.debug("Adding IETF-ACL for sub-interface: {}(id={}): {}", subInterfaceName, subInterfaceIndex, dataAfter); + + final AccessLists accessLists = dataAfter.getAccessLists(); + checkArgument(accessLists != null && accessLists.getAcl() != null, + "ietf-acl container does not define acl list"); + + final Optional subInterfaceOptional = + writeContext.readAfter(id.firstIdentifierOf(SubInterface.class)); + checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id); + final SubInterface subInterface = subInterfaceOptional.get(); + + if (!InterfaceMode.L2.equals(accessLists.getMode())) { + LOG.debug("Writing egress Acls is supported only in L2 mode. Ignoring config: {}", dataAfter); + return; + } + + aclWriter + .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, + @Nonnull final Egress dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Sub-interface ACLs update: removing previously configured ACLs"); + deleteCurrentAttributes(id, dataBefore, writeContext); + LOG.debug("Sub-interface ACLs update: adding updated ACLs"); + writeCurrentAttributes(id, dataAfter, writeContext); + LOG.debug("Sub-interface ACLs update was successful"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); + aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclCustomizer.java new file mode 100644 index 000000000..05233ce40 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclCustomizer.java @@ -0,0 +1,83 @@ +/* + * 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.acl.ingress; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for enabling/disabling ingress ACLs on given interface based on low lever classfier model. + */ +public class AclCustomizer extends FutureJVppCustomizer implements WriterCustomizer, AclWriter { + + private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class); + private final NamingContext interfaceContext; + private final VppClassifierContextManager classifyTableContext; + + public AclCustomizer(@Nonnull final FutureJVppCore vppApi, @Nonnull final NamingContext interfaceContext, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(vppApi); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + setAcl(true, id, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final Ingress dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + throw new UnsupportedOperationException("Acl update is not supported. Please delete Acl container first."); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + setAcl(false, id, dataBefore, writeContext); + } + + private void setAcl(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final Ingress acl, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + + LOG.debug("Setting ACL(isAdd={}) on interface={}(id={}): {}", isAdd, ifName, ifIndex, acl); + + inputAclSetInterface(getFutureJVpp(), isAdd, id, acl, ifIndex, classifyTableContext, + writeContext.getMappingContext()); + LOG.debug("Successfully set ACL(isAdd={}) on interface={}(id={}): {}", isAdd, ifName, ifIndex, acl); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclWriter.java new file mode 100644 index 000000000..da74f0a8d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/AclWriter.java @@ -0,0 +1,73 @@ +/* + * 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.acl.ingress; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.AclBaseAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +interface AclWriter extends ByteDataTranslator, JvppReplyConsumer { + + default void inputAclSetInterface(@Nonnull final FutureJVppCore futureJVppCore, final boolean isAdd, + @Nonnull final InstanceIdentifier id, @Nonnull final AclBaseAttributes acl, + @Nonnegative final int ifIndex, + @Nonnull final VppClassifierContextManager classifyTableContext, + @Nonnull final MappingContext mappingContext) throws WriteFailedException { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = booleanToByte(isAdd); + request.swIfIndex = ifIndex; + request.l2TableIndex = ~0; // skip + request.ip4TableIndex = ~0; // skip + request.ip6TableIndex = ~0; // skip + + final L2Acl l2Acl = acl.getL2Acl(); + if (l2Acl != null) { + final String tableName = checkNotNull(l2Acl.getClassifyTable(), "L2 classify table is null"); + request.l2TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); + } + final Ip4Acl ip4Acl = acl.getIp4Acl(); + if (ip4Acl != null) { + final String tableName = checkNotNull(ip4Acl.getClassifyTable(), "IPv4 classify table is null"); + request.ip4TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); + } + final Ip6Acl ip6Acl = acl.getIp6Acl(); + if (ip6Acl != null) { + final String tableName = checkNotNull(ip6Acl.getClassifyTable(), "IPv6 classify table is null"); + request.ip6TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); + } + + final CompletionStage inputAclSetInterfaceReplyCompletionStage = + futureJVppCore.inputAclSetInterface(request); + + getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizer.java new file mode 100644 index 000000000..e4003fc9d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizer.java @@ -0,0 +1,89 @@ +/* + * 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.acl.ingress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.v3po.rev161214.interfaces._interface.ietf.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for enabling/disabling ingress ACLs for given interface (as defined in ietf-acl model). + * + * The customizer assumes it owns classify table management for interfaces where ietf-acl container is present. Using + * low level classifier model or direct changes to classify tables in combination with ietf-acls are not supported and + * can result in unpredictable behaviour. + */ +public class IetfAclCustomizer implements WriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(IetfAclCustomizer.class); + private final IngressIetfAclWriter aclWriter; + private final NamingContext interfaceContext; + + public IetfAclCustomizer(@Nonnull final IngressIetfAclWriter aclWriter, + @Nonnull final NamingContext interfaceContext) { + this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + LOG.debug("Adding ACLs for interface={}(id={}): {}", ifName, ifIndex, dataAfter); + + final AccessLists accessLists = dataAfter.getAccessLists(); + checkArgument(accessLists != null && accessLists.getAcl() != null, + "ietf-acl container does not define acl list"); + + aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("ACLs update: removing previously configured ACLs"); + deleteCurrentAttributes(id, dataBefore, writeContext); + LOG.debug("ACLs update: adding updated ACLs"); + writeCurrentAttributes(id, dataAfter, writeContext); + LOG.debug("ACLs update was successful"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); + final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); + LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); + aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java new file mode 100644 index 000000000..022d21861 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java @@ -0,0 +1,118 @@ +/* + * 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.acl.ingress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.v3po.interfaces.acl.common.AbstractIetfAclWriter; +import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class IngressIetfAclWriter extends AbstractIetfAclWriter { + private final AclTableContextManager aclCtx; + + public IngressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { + super(futureJVppCore); + this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); + } + + @Override + public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); + checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); + final MappingEntry entry = optional.get(); + unassignClassifyTables(id, entry); + removeClassifyTables(id, entry); + aclCtx.removeEntry(swIfIndex, mappingContext); + } + + private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, + @Nonnull final MappingEntry entry) + throws WriteFailedException { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = 0; + request.swIfIndex = entry.getIndex(); + request.l2TableIndex = entry.getL2TableId(); + request.ip4TableIndex = entry.getIp4TableId(); + request.ip6TableIndex = entry.getIp6TableId(); + final CompletionStage inputAclSetInterfaceReplyCompletionStage = + jvpp.inputAclSetInterface(request); + getReplyForDelete(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); + } + + @Override + public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, + @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, + @Nonnull final MappingContext mappingContext) + throws WriteFailedException { + checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); + + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = 1; + request.swIfIndex = swIfIndex; + request.l2TableIndex = NOT_DEFINED; + request.ip4TableIndex = NOT_DEFINED; + request.ip6TableIndex = NOT_DEFINED; + + if (InterfaceMode.L2.equals(mode)) { + final List aces = getACEs(acls, writeContext, ace -> true); + request.l2TableIndex = writeAces(id, aces, defaultAction, mode, numberOfTags); + } else { + final List ip4Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp4Path)); + request.ip4TableIndex = writeAces(id, ip4Aces, defaultAction, mode, numberOfTags); + final List ip6Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp6Path)); + request.ip6TableIndex = writeAces(id, ip6Aces, defaultAction, mode, numberOfTags); + } + + final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) + .setIp4TableId(request.ip4TableIndex) + .setIp6TableId(request.ip6TableIndex) + .setL2TableId(request.l2TableIndex) + .build(); + aclCtx.addEntry(entry, mappingContext); + + try { + getReplyForWrite(jvpp.inputAclSetInterface(request).toCompletableFuture(), id); + } catch (WriteFailedException e) { + removeClassifyTables(id, entry); + throw e; + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java new file mode 100644 index 000000000..b0be5d71f --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java @@ -0,0 +1,93 @@ +/* + * 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.acl.ingress; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.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.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for enabling/disabling ingress ACLs on given sub-interface. + */ +public class SubInterfaceAclCustomizer extends FutureJVppCustomizer + implements WriterCustomizer, AclWriter { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class); + private final NamingContext interfaceContext; + private final VppClassifierContextManager classifyTableContext; + + public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceContext, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(vppApi); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + setAcl(true, id, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final Ingress dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + throw new UnsupportedOperationException("Acl update is not supported. Please delete Acl container first."); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + setAcl(false, id, dataBefore, writeContext); + } + + private void setAcl(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final Ingress acl, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + final String subInterfaceName = SubInterfaceUtils + .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + + LOG.debug("Setting ACL(isAdd={}) on sub-interface={}(id={}): {}", + isAdd, subInterfaceName, subInterfaceIndex, acl); + inputAclSetInterface(getFutureJVpp(), isAdd, id, acl, subInterfaceIndex, classifyTableContext, + writeContext.getMappingContext()); + LOG.debug("Successfully set ACL(isAdd={}) on sub-interface={}(id={}): {}", + isAdd, subInterfaceName, subInterfaceIndex, acl); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java new file mode 100644 index 000000000..4f24906a1 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java @@ -0,0 +1,108 @@ +/* + * 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.acl.ingress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getNumberOfTags; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for enabling/disabling ingress ACLs for given sub-interface (as defined in ietf-acl model). + * + * The customizer assumes it owns classify table management for sub-interfaces where ietf-acl container is present. + * Using low level classifier model or direct changes to classify tables in combination with ietf-acls are not supported + * and can result in unpredictable behaviour. + */ +public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIetfAclCustomizer.class); + private final IngressIetfAclWriter aclWriter; + private final NamingContext interfaceContext; + + public SubInterfaceIetfAclCustomizer(@Nonnull final IngressIetfAclWriter aclWriter, + @Nonnull final NamingContext interfaceContext) { + this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + return SubInterfaceUtils + .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + LOG.debug("Adding IETF-ACL for sub-interface: {}(id={}): {}", subInterfaceName, subInterfaceIndex, dataAfter); + + final AccessLists accessLists = dataAfter.getAccessLists(); + checkArgument(accessLists != null && accessLists.getAcl() != null, + "ietf-acl container does not define acl list"); + + final Optional subInterfaceOptional = + writeContext.readAfter(id.firstIdentifierOf(SubInterface.class)); + checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id); + final SubInterface subInterface = subInterfaceOptional.get(); + + aclWriter + .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, @Nonnull final Ingress dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Sub-interface ACLs update: removing previously configured ACLs"); + deleteCurrentAttributes(id, dataBefore, writeContext); + LOG.debug("Sub-interface ACLs update: adding updated ACLs"); + writeCurrentAttributes(id, dataAfter, writeContext); + LOG.debug("Sub-interface ACLs update was successful"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ingress dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); + aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizer.java new file mode 100644 index 000000000..6a6bb6c35 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizer.java @@ -0,0 +1,151 @@ +/* + * 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.ip; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.v3po.interfaces.ip.subnet.validation.SubnetValidationException; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.v3po.interfaces.ip.subnet.validation.SubnetValidator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for writing {@link Address} + */ +public class Ipv4AddressCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, Ipv4Writer { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressCustomizer.class); + private final NamingContext interfaceContext; + private final SubnetValidator subnetValidator; + + Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext, + @Nonnull final SubnetValidator subnetValidator) { + super(futureJVppCore); + this.interfaceContext = checkNotNull(interfaceContext, "Interface context cannot be null"); + this.subnetValidator = checkNotNull(subnetValidator, "Subnet validator cannot be null"); + } + + public Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + this(futureJVppCore, interfaceContext, new SubnetValidator()); + } + + @Override + public void writeCurrentAttributes(InstanceIdentifier
id, Address dataAfter, WriteContext writeContext) + throws WriteFailedException { + + final String interfaceName = id.firstKeyOf(Interface.class).getName(); + final int interfaceIndex = interfaceContext.getIndex(interfaceName, writeContext.getMappingContext()); + + // checks whether address is not from same subnet of some address already defined on this interface + try { + + final InstanceIdentifier parentId = RWUtils.cutId(id, InstanceIdentifier.create(Ipv4.class)); + final Optional ipv4Optional = writeContext.readAfter(parentId); + + //no need to check isPresent() - we are inside of address customizer, therefore there must be Address data + //that is being processed by infrastructure + + subnetValidator.checkNotAddingToSameSubnet(ipv4Optional.get().getAddress()); + } catch (SubnetValidationException e) { + throw new WriteFailedException(id, e); + } + + setAddress(true, id, interfaceName, interfaceIndex, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(InstanceIdentifier
id, Address dataBefore, Address dataAfter, + WriteContext writeContext) throws WriteFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Operation not supported")); + } + + @Override + public void deleteCurrentAttributes(InstanceIdentifier
id, Address dataBefore, WriteContext writeContext) + throws WriteFailedException { + + final String interfaceName = id.firstKeyOf(Interface.class).getName(); + final int interfaceIndex = interfaceContext.getIndex(interfaceName, writeContext.getMappingContext()); + + setAddress(false, id, interfaceName, interfaceIndex, dataBefore, writeContext); + } + + private void setAddress(boolean add, final InstanceIdentifier
id, final String interfaceName, + final int interfaceIndex, final Address address, + final WriteContext writeContext) throws WriteFailedException { + + Subnet subnet = address.getSubnet(); + + if (subnet instanceof PrefixLength) { + setPrefixLengthSubnet(add, id, interfaceName, interfaceIndex, address, (PrefixLength) subnet); + } else if (subnet instanceof Netmask) { + setNetmaskSubnet(add, id, interfaceName, interfaceIndex, address, (Netmask) subnet); + } else { + LOG.error("Unable to handle subnet of type {}", subnet.getClass()); + throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass()); + } + } + + private void setNetmaskSubnet(final boolean add, @Nonnull final InstanceIdentifier
id, + @Nonnull final String interfaceName, final int interfaceIndex, + @Nonnull final Address address, @Nonnull final Netmask subnet) + throws WriteFailedException { + + LOG.debug("Setting Subnet(subnet-mask) for interface: {}(id={}). Subnet: {}, address: {}", + interfaceName, interfaceIndex, subnet, address); + + final DottedQuad netmask = subnet.getNetmask(); + checkNotNull(netmask, "netmask value should not be null"); + + final byte subnetLength = getSubnetMaskLength(netmask.getValue()); + addDelAddress(getFutureJVpp(), add, id, interfaceIndex, address.getIp(), subnetLength); + } + + private void setPrefixLengthSubnet(final boolean add, @Nonnull final InstanceIdentifier
id, + @Nonnull final String interfaceName, final int interfaceIndex, + @Nonnull final Address address, @Nonnull final PrefixLength subnet) + throws WriteFailedException { + LOG.debug("Setting Subnet(prefix-length) for interface: {}(id={}). Subnet: {}, address: {}", + interfaceName, interfaceIndex, subnet, address); + + addDelAddress(getFutureJVpp(), add, id, interfaceIndex, address.getIp(), + subnet.getPrefixLength().byteValue()); + + LOG.debug("Subnet(prefix-length) set successfully for interface: {}(id={}). Subnet: {}, address: {}", + interfaceName, interfaceIndex, subnet, address); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Customizer.java new file mode 100644 index 000000000..ff86331b1 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Customizer.java @@ -0,0 +1,56 @@ +/* + * 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.ip; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Ipv4Customizer extends FutureJVppCustomizer implements WriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class); + + public Ipv4Customizer(final FutureJVppCore vppApi) { + super(vppApi); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ipv4 dataAfter, @Nonnull final WriteContext writeContext) { + LOG.debug("Handling Ipv4 leaves (mtu, forwarding) is not supported by VPP API. Ignoring configuration"); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ipv4 dataBefore, @Nonnull final Ipv4 dataAfter, + @Nonnull final WriteContext writeContext) { + LOG.debug("Handling Ipv4 leaves (mtu, forwarding) is not supported by VPP API. Ignoring configuration"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ipv4 dataBefore, @Nonnull final WriteContext writeContext) { + LOG.debug("Handling Ipv4 leaves (mtu, forwarding) is not supported by VPP API. Ignoring configuration"); + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java new file mode 100644 index 000000000..1a1c2d2c0 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java @@ -0,0 +1,126 @@ +/* + * 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.ip; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +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.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.IpNeighborAddDel; +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.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Customizer for writing {@link Neighbor} for {@link Ipv4}. + */ +public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, ByteDataTranslator, AddressTranslator, + JvppReplyConsumer { + + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); + final NamingContext interfaceContext; + + public Ipv4NeighbourCustomizer(final FutureJVppCore futureJVppCore, final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = interfaceContext; + } + + @Override + public void writeCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull Neighbor dataAfter, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + checkNotNull(dataAfter, "Cannot write null neighbour"); + checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found"); + + LOG.debug("Processing request for Neigbour write"); + String interfaceName = id.firstKeyOf(Interface.class).getName(); + MappingContext mappingContext = writeContext.getMappingContext(); + + checkState(interfaceContext.containsIndex(interfaceName, mappingContext), + "Mapping does not contains mapping for provider interface name ".concat(interfaceName)); + + LOG.debug("Parent interface index found"); + addDelNeighbourAndReply(id, true, + interfaceContext.getIndex(interfaceName, mappingContext), dataAfter); + LOG.info("Neighbour successfully written"); + } + + @Override + public void updateCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull Neighbor dataBefore, + @Nonnull Neighbor dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull Neighbor dataBefore, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + checkNotNull(dataBefore, "Cannot delete null neighbour"); + checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found"); + + LOG.debug("Processing request for Neigbour delete"); + String interfaceName = id.firstKeyOf(Interface.class).getName(); + MappingContext mappingContext = writeContext.getMappingContext(); + + checkState(interfaceContext.containsIndex(interfaceName, mappingContext), + "Mapping does not contains mapping for provider interface name %s", interfaceName); + + LOG.debug("Parent interface[{}] index found", interfaceName); + + addDelNeighbourAndReply(id, false, + interfaceContext.getIndex(interfaceName, mappingContext), dataBefore); + LOG.info("Neighbour {} successfully deleted", id); + } + + private void addDelNeighbourAndReply(InstanceIdentifier id, boolean add, int parentInterfaceIndex, + Neighbor data) throws WriteFailedException { + + IpNeighborAddDel request = new IpNeighborAddDel(); + + request.isAdd = booleanToByte(add); + request.isIpv6 = 0; + request.isStatic = 1; + request.dstAddress = ipv4AddressNoZoneToArray(data.getIp()); + request.macAddress = parseMac(data.getLinkLayerAddress().getValue()); + request.swIfIndex = parentInterfaceIndex; + + //TODO HONEYCOMB-182 if it is necessary for future use ,make adjustments to be able to set vrfid + //request.vrfId + getReplyForWrite(getFutureJVpp().ipNeighborAddDel(request).toCompletableFuture(), id); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Writer.java new file mode 100644 index 000000000..36e1800e1 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Writer.java @@ -0,0 +1,108 @@ +/* + * 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.ip; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddress; +import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddressReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Utility class providing Ipv4 CUD support. + */ +public interface Ipv4Writer extends ByteDataTranslator, Ipv4Translator, JvppReplyConsumer { + + int DOTTED_QUAD_MASK_LENGTH = 4; + int IPV4_ADDRESS_PART_BITS_COUNT = 8; + int NETMASK_PART_LIMIT = 256; // 2 power to 8 + + default void addDelAddress(@Nonnull final FutureJVppCore futureJVppCore, final boolean add, + final InstanceIdentifier id, + @Nonnegative final int ifaceId, + @Nonnull final Ipv4AddressNoZone address, @Nonnegative final byte prefixLength) + throws WriteFailedException { + checkArgument(prefixLength > 0, "Invalid prefix length"); + checkNotNull(address, "address should not be null"); + + final byte[] addressBytes = ipv4AddressNoZoneToArray(address); + + final CompletionStage swInterfaceAddDelAddressReplyCompletionStage = + futureJVppCore.swInterfaceAddDelAddress( + getSwInterfaceAddDelAddressRequest(ifaceId, booleanToByte(add) /* isAdd */, + (byte) 0 /* isIpv6 */, (byte) 0 /* delAll */, prefixLength, addressBytes)); + + getReplyForWrite(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture(), id); + } + + default SwInterfaceAddDelAddress getSwInterfaceAddDelAddressRequest(final int swIfc, final byte isAdd, + final byte ipv6, final byte deleteAll, + final byte length, final byte[] addr) { + final SwInterfaceAddDelAddress swInterfaceAddDelAddress = new SwInterfaceAddDelAddress(); + swInterfaceAddDelAddress.swIfIndex = swIfc; + swInterfaceAddDelAddress.isAdd = isAdd; + swInterfaceAddDelAddress.isIpv6 = ipv6; + swInterfaceAddDelAddress.delAll = deleteAll; + swInterfaceAddDelAddress.address = addr; + swInterfaceAddDelAddress.addressLength = length; + return swInterfaceAddDelAddress; + } + + /** + * Returns the prefix size in bits of the specified subnet mask. Example: For the subnet mask 255.255.255.128 it + * returns 25 while for 255.0.0.0 it returns 8. If the passed subnetMask array is not complete or contains not only + * leading ones, IllegalArgumentExpression is thrown + * + * @param mask the subnet mask in dot notation 255.255.255.255 + * @return the prefix length as number of bits + */ + default byte getSubnetMaskLength(final String mask) { + String[] maskParts = mask.split("\\."); + + checkArgument(maskParts.length == DOTTED_QUAD_MASK_LENGTH, + "Network mask %s is not in Quad Dotted Decimal notation!", mask); + + long maskAsNumber = 0; + for (int i = 0; i < DOTTED_QUAD_MASK_LENGTH; i++) { + maskAsNumber <<= IPV4_ADDRESS_PART_BITS_COUNT; + int value = Integer.parseInt(maskParts[i]); + checkArgument(value < NETMASK_PART_LIMIT, "Network mask %s contains invalid number(s) over 255!", mask); + checkArgument(value >= 0, "Network mask %s contains invalid negative number(s)!", mask); + maskAsNumber += value; + } + + String bits = Long.toBinaryString(maskAsNumber); + checkArgument(bits.length() == IPV4_ADDRESS_PART_BITS_COUNT * DOTTED_QUAD_MASK_LENGTH, + "Incorrect network mask %s", mask); + final int leadingOnes = bits.indexOf('0'); + checkArgument(leadingOnes != -1, "Broadcast address %s is not allowed!", mask); + checkArgument(bits.substring(leadingOnes).indexOf('1') == -1, + "Non-contiguous network mask %s is not allowed!", mask); + return (byte) leadingOnes; + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv6Customizer.java new file mode 100644 index 000000000..85f190d83 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv6Customizer.java @@ -0,0 +1,55 @@ +/* + * 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.ip; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Ipv6Customizer extends FutureJVppCustomizer implements WriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv6Customizer.class); + + public Ipv6Customizer(final FutureJVppCore vppApi) { + super(vppApi); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ipv6 dataAfter, @Nonnull final WriteContext writeContext) { + LOG.warn("Unsupported, ignoring configuration {}", dataAfter); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ipv6 dataBefore, @Nonnull final Ipv6 dataAfter, + @Nonnull final WriteContext writeContext) { + LOG.warn("Unsupported, ignoring configuration {}", dataAfter); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Ipv6 dataBefore, @Nonnull final WriteContext writeContext) { + LOG.warn("Unsupported, ignoring configuration delete {}", id); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java new file mode 100644 index 000000000..214ff36c4 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java @@ -0,0 +1,131 @@ +/* + * 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.ip; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +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.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.DottedQuad; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.Subnet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.Netmask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Write customizer for sub-interface {@link Address} + */ +public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, Ipv4Writer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class); + private final NamingContext interfaceContext; + + public SubInterfaceIpv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = checkNotNull(interfaceContext, "interface context should not be null"); + } + + @Override + public void writeCurrentAttributes(InstanceIdentifier
id, Address dataAfter, WriteContext writeContext) + throws WriteFailedException { + setAddress(true, id, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(InstanceIdentifier
id, Address dataBefore, Address dataAfter, + WriteContext writeContext) throws WriteFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Operation not supported")); + } + + @Override + public void deleteCurrentAttributes(InstanceIdentifier
id, Address dataBefore, WriteContext writeContext) + throws WriteFailedException { + setAddress(false, id, dataBefore, writeContext); + } + + private void setAddress(boolean add, final InstanceIdentifier
id, final Address address, + final WriteContext writeContext) throws WriteFailedException { + + final String interfaceName = id.firstKeyOf(Interface.class).getName(); + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); + + Subnet subnet = address.getSubnet(); + + if (subnet instanceof PrefixLength) { + setPrefixLengthSubnet(add, id, interfaceName, subInterfaceIndex, address, (PrefixLength) subnet); + } else if (subnet instanceof Netmask) { + setNetmaskSubnet(add, id, interfaceName, subInterfaceIndex, address, (Netmask) subnet); + } else { + LOG.error("Unable to handle subnet of type {}", subnet.getClass()); + throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass()); + } + } + + private String getSubInterfaceName(@Nonnull final InstanceIdentifier
id) { + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + return SubInterfaceUtils + .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + } + + private void setNetmaskSubnet(final boolean add, @Nonnull final InstanceIdentifier
id, + @Nonnull final String subInterfaceName, final int subInterfaceIndex, + @Nonnull final Address address, @Nonnull final Netmask subnet) + throws WriteFailedException { + + LOG.debug("Setting Subnet(subnet-mask) for sub-interface: {}(id={}). Subnet: {}, address: {}", + subInterfaceName, subInterfaceIndex, subnet, address); + + final DottedQuad netmask = subnet.getNetmask(); + checkNotNull(netmask, "netmask value should not be null"); + + final byte subnetLength = getSubnetMaskLength(netmask.getValue()); + addDelAddress(getFutureJVpp(), add, id, subInterfaceIndex, address.getIp(), subnetLength); + } + + private void setPrefixLengthSubnet(final boolean add, @Nonnull final InstanceIdentifier
id, + @Nonnull final String subInterfaceName, final int subInterfaceIndex, + @Nonnull final Address address, @Nonnull final PrefixLength subnet) + throws WriteFailedException { + LOG.debug("Setting Subnet(prefix-length) for sub-interface: {}(id={}). Subnet: {}, address: {}", + subInterfaceName, subInterfaceIndex, subnet, address); + + addDelAddress(getFutureJVpp(), add, id, subInterfaceIndex, address.getIp(), + subnet.getPrefixLength().byteValue()); + + LOG.debug("Subnet(prefix-length) set successfully for sub-interface: {}(id={}). Subnet: {}, address: {}", + subInterfaceName, subInterfaceIndex, subnet, address); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidationException.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidationException.java new file mode 100644 index 000000000..001923093 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidationException.java @@ -0,0 +1,50 @@ +/* + * 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.ip.subnet.validation; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Collection; +import javax.annotation.Nonnull; +import org.apache.commons.lang3.StringUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; + +/** + * Thrown as negative result of subnet validation + */ +public class SubnetValidationException extends Exception { + + private SubnetValidationException(@Nonnull final String message) { + super(message); + } + + public static SubnetValidationException forConflictingData(@Nonnull final Short prefix, @Nonnull Collection
addresses) { + return new SubnetValidationException( + "Attempt to define multiple addresses for same subnet[prefixLen = " + prefixToString(prefix) + "], " + + "addresses : " + addressesToString(addresses)); + } + + private static String prefixToString(final Short prefix) { + return checkNotNull(prefix, "Cannot create " + SubnetValidationException.class.getName() + " for null prefix") + .toString(); + } + + private static String addressesToString(final Collection
addresses) { + return StringUtils.join(checkNotNull(addresses, + "Cannot create " + SubnetValidationException.class.getName() + " for null address list"), " | "); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidator.java new file mode 100644 index 000000000..c5b011e07 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidator.java @@ -0,0 +1,80 @@ +/* + * 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.ip.subnet.validation; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import io.fd.hc2vpp.v3po.interfaces.ip.Ipv4Writer; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength; + +/** + * Validator for detecting if there is an attempt to assign multiple addresses from same subnet + */ +public class SubnetValidator implements Ipv4Writer { + + /** + * Checks whether data provided for writing are not in collision with already existing data + */ + public void checkNotAddingToSameSubnet(@Nonnull final List
addresses) + throws SubnetValidationException { + + final Multimap prefixLengthRegister = Multimaps.index(addresses, toPrefixLength()); + final int keySetSize = prefixLengthRegister.keySet().size(); + + if (keySetSize == 0 || keySetSize == addresses.size()) { + //this means that every key is unique(has only one value) or no addresses were prefix-length based ,so there is no conflict + return; + } + + //finds conflicting prefix + final Short conflictingPrefix = prefixLengthRegister.keySet() + .stream() + .filter(a -> prefixLengthRegister.get(a).size() > 1) + .findFirst() + .get(); + + //and reports it with affected addresses + throw SubnetValidationException + .forConflictingData(conflictingPrefix, prefixLengthRegister.get(conflictingPrefix)); + } + + private Function toPrefixLength() { + return (final Address address) -> { + final Subnet subnet = address.getSubnet(); + + if (subnet instanceof PrefixLength) { + return ((PrefixLength) subnet).getPrefixLength(); + } + + if (address.getSubnet() instanceof Netmask) { + return (short) getSubnetMaskLength( + checkNotNull(((Netmask) subnet).getNetmask(), "No netmask defined for %s", subnet) + .getValue()); + } + + throw new IllegalArgumentException("Unsupported subnet : " + subnet); + }; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizer.java new file mode 100644 index 000000000..3e8d82399 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/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.hc2vpp.v3po.interfaces.pbb; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.hc2vpp.common.translate.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.rev161214.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/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java new file mode 100644 index 000000000..33b71b1e4 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java @@ -0,0 +1,108 @@ +/* + * 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; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Ethernet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.EthernetBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class EthernetCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, InterfaceDataTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class); + private NamingContext interfaceContext; + + public EthernetCustomizer(@Nonnull final FutureJVppCore jvpp, + @Nonnull final NamingContext interfaceContext) { + super(jvpp); + this.interfaceContext = interfaceContext; + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, + @Nonnull final Ethernet readValue) { + ((VppInterfaceStateAugmentationBuilder) parentBuilder).setEthernet(readValue); + } + + @Nonnull + @Override + public EthernetBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new EthernetBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final EthernetBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + + final InterfaceKey key = id.firstKeyOf(Interface.class); + final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), + interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache(), LOG); + + if (iface.linkMtu != 0) { + builder.setMtu((int) iface.linkMtu); + } + + switch (iface.linkDuplex) { + case 1: + builder.setDuplex(Ethernet.Duplex.Half); + break; + case 2: + builder.setDuplex(Ethernet.Duplex.Full); + break; + default: + break; + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final Ethernet readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.EthernetBuilder() + .setMtu(readValue.getMtu()) + .build()); + } + + private InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAugmentation.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Ethernet.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java new file mode 100644 index 000000000..b31ab74d5 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 Intel 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; + +import static com.google.common.base.Preconditions.checkState; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.GreTunnelDetails; +import io.fd.vpp.jvpp.core.dto.GreTunnelDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.GreTunnelDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.GreTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Gre; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.GreBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GreCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, InterfaceDataTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(GreCustomizer.class); + private NamingContext interfaceContext; + + public GreCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + super(jvpp); + this.interfaceContext = interfaceContext; + } + + @Override + public void merge(@Nonnull Builder parentBuilder, + @Nonnull Gre readValue) { + ((VppInterfaceStateAugmentationBuilder) parentBuilder).setGre(readValue); + } + + @Nonnull + @Override + public GreBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new GreBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final GreBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + final InterfaceKey key = id.firstKeyOf(Interface.class); + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, GreTunnel.class, LOG)) { + return; + } + + LOG.debug("Reading attributes for gre tunnel: {}", key.getName()); + // Dump just a single + final GreTunnelDump request = new GreTunnelDump(); + request.swIfIndex = index; + + final CompletionStage swInterfaceGreDetailsReplyDumpCompletionStage = + getFutureJVpp().greTunnelDump(request); + final GreTunnelDetailsReplyDump reply = + getReplyForRead(swInterfaceGreDetailsReplyDumpCompletionStage.toCompletableFuture(), id); + + // VPP keeps gre tunnel interfaces even after they were deleted (optimization) + // However there ar no longer any gre tunnel specific fields assigned to it and this call + // returns nothing + if (reply == null || reply.greTunnelDetails == null || reply.greTunnelDetails.isEmpty()) { + LOG.debug( + "Gre tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + + "after delete", key.getName(), index); + return; + } + + checkState(reply.greTunnelDetails.size() == 1, + "Unexpected number of returned gre tunnels: {} for tunnel: {}", reply.greTunnelDetails, + key.getName()); + LOG.trace("Gre tunnel: {} attributes returned from VPP: {}", key.getName(), reply); + + final GreTunnelDetails swInterfaceGreDetails = reply.greTunnelDetails.get(0); + if (swInterfaceGreDetails.isIpv6 == 1) { + final Ipv6Address dstIpv6 = + new Ipv6Address(parseAddress(swInterfaceGreDetails.dstAddress).getHostAddress()); + builder.setDst(new IpAddress(dstIpv6)); + final Ipv6Address srcIpv6 = + new Ipv6Address(parseAddress(swInterfaceGreDetails.srcAddress).getHostAddress()); + builder.setSrc(new IpAddress(srcIpv6)); + } else { + final byte[] dstBytes = Arrays.copyOfRange(swInterfaceGreDetails.dstAddress, 0, 4); + final Ipv4Address dstIpv4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); + builder.setDst(new IpAddress(dstIpv4)); + final byte[] srcBytes = Arrays.copyOfRange(swInterfaceGreDetails.srcAddress, 0, 4); + final Ipv4Address srcIpv4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); + builder.setSrc(new IpAddress(srcIpv4)); + } + builder.setOuterFibId((long) swInterfaceGreDetails.outerFibId); + LOG.debug("Gre tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); + } + + @Nonnull + private static InetAddress parseAddress(@Nonnull final byte[] addr) { + try { + return InetAddress.getByAddress(addr); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e); + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final Gre readValue, @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.GreBuilder() + .setDst(readValue.getDst()) + .setSrc(readValue.getSrc()) + .setOuterFibId(readValue.getOuterFibId()) + .build()); + } + + private InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAugmentation.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java new file mode 100644 index 000000000..3893d37a1 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java @@ -0,0 +1,125 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; +import io.fd.vpp.jvpp.core.dto.BridgeDomainSwIfDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility class providing Interconnection read support. + */ +final class InterconnectionReadUtils implements InterfaceDataTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(InterconnectionReadUtils.class); + + private final FutureJVppCore futureJVppCore; + private final NamingContext interfaceContext; + private final NamingContext bridgeDomainContext; + + InterconnectionReadUtils(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext bridgeDomainContext) { + this.futureJVppCore = requireNonNull(futureJVppCore, "futureJVppCore should not be null"); + this.interfaceContext = requireNonNull(interfaceContext, "interfaceContext should not be null"); + this.bridgeDomainContext = requireNonNull(bridgeDomainContext, "bridgeDomainContext should not be null"); + } + + @Nullable + Interconnection readInterconnection(@Nonnull final InstanceIdentifier id, @Nonnull final String ifaceName, + @Nonnull final ReadContext ctx) + throws ReadFailedException { + final int ifaceId = interfaceContext.getIndex(ifaceName, ctx.getMappingContext()); + + final SwInterfaceDetails iface = getVppInterfaceDetails(futureJVppCore, id, ifaceName, + ifaceId, ctx.getModificationCache(), LOG); + LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface); + + final BridgeDomainDetailsReplyDump dumpReply = getDumpReply(id); + final Optional bdForInterface = getBridgeDomainForInterface(ifaceId, dumpReply); + if (bdForInterface.isPresent()) { + final BridgeDomainSwIfDetails bdSwIfDetails = bdForInterface.get(); + final BridgeBasedBuilder bbBuilder = new BridgeBasedBuilder(); + bbBuilder.setBridgeDomain(bridgeDomainContext.getName(bdSwIfDetails.bdId, ctx.getMappingContext())); + + // Set BVI if the bridgeDomainDetails.bviSwIfIndex == current sw if index + final Optional bridgeDomainForInterface = + getBridgeDomainForInterface(dumpReply, bdForInterface.get().bdId); + // Since we already found an interface assigned to a bridge domain, the details for BD must be present + checkState(bridgeDomainForInterface.isPresent()); + if (bridgeDomainForInterface.get().bviSwIfIndex == ifaceId) { + bbBuilder.setBridgedVirtualInterface(true); + } else { + bbBuilder.setBridgedVirtualInterface(false); + } + + if (bdSwIfDetails.shg != 0) { + bbBuilder.setSplitHorizonGroup((short) bdSwIfDetails.shg); + } + return bbBuilder.build(); + } + // TODO HONEYCOMB-190 is there a way to check if interconnection is XconnectBased? + + return null; + } + + private Optional getBridgeDomainForInterface(final int ifaceId, + final BridgeDomainDetailsReplyDump reply) { + if (null == reply || null == reply.bridgeDomainSwIfDetails || reply.bridgeDomainSwIfDetails.isEmpty()) { + return Optional.empty(); + } + // interface can be added to only one BD only + return reply.bridgeDomainSwIfDetails.stream().filter(a -> a.swIfIndex == ifaceId).findFirst(); + } + + private Optional getBridgeDomainForInterface(final BridgeDomainDetailsReplyDump reply, + int bdId) { + return reply.bridgeDomainDetails.stream().filter(a -> a.bdId == bdId).findFirst(); + } + + private BridgeDomainDetailsReplyDump getDumpReply(@Nonnull final InstanceIdentifier id) + throws ReadFailedException { + // We need to perform full bd dump, because there is no way + // to ask VPP for BD details given interface id/name (TODO HONEYCOMB-190 add it to vpp.api?) + // TODO HONEYCOMB-190 cache dump result + final BridgeDomainDump request = new BridgeDomainDump(); + request.bdId = -1; + + final CompletableFuture bdCompletableFuture = + futureJVppCore.bridgeDomainSwIfDump(request).toCompletableFuture(); + return getReplyForRead(bdCompletableFuture, id); + + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java new file mode 100644 index 000000000..70bc0c62b --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java @@ -0,0 +1,232 @@ +/* + * 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; + +import io.fd.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for reading ietf-interfaces:interfaces-state/interface. + */ +public class InterfaceCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, ByteDataTranslator, + InterfaceDataTranslator { + + public static final String DUMPED_IFCS_CONTEXT_KEY = + InterfaceCustomizer.class.getName() + "dumpedInterfacesDuringGetAllIds"; + private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); + private final NamingContext interfaceNamingContext; + private final DisabledInterfacesManager interfaceDisableContext; + + public InterfaceCustomizer(@Nonnull final FutureJVppCore jvpp, + @Nonnull final NamingContext interfaceNamingContext, + @Nonnull final DisabledInterfacesManager interfaceDisableContext) { + super(jvpp); + this.interfaceNamingContext = interfaceNamingContext; + this.interfaceDisableContext = interfaceDisableContext; + } + + public static void cacheInterfaceDump(final @Nonnull ReadContext context, final SwInterfaceDetailsReplyDump ifaces) { + context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); + } + + @Nonnull + @SuppressWarnings("unchecked") + public static Map getCachedInterfaceDump(@Nonnull final ModificationCache ctx) { + return ctx.get(DUMPED_IFCS_CONTEXT_KEY) == null + ? new HashMap<>() + // allow customizers to update the cache + : (Map) ctx.get(DUMPED_IFCS_CONTEXT_KEY); + } + + private static boolean isRegularInterface(final SwInterfaceDetails iface) { + return iface.subId == 0; + } + + @Nonnull + @Override + public InterfaceBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new InterfaceBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull InterfaceBuilder builder, + @Nonnull ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading attributes for interface: {}", id); + final String ifaceName = id.firstKeyOf(id.getTargetType()).getName(); + + final int index = interfaceNamingContext.getIndex(ifaceName, ctx.getMappingContext()); + + // Ignore disabled interface (such as deleted VXLAN tunnels) + if (interfaceDisableContext.isInterfaceDisabled(index, ctx.getMappingContext())) { + LOG.debug("Skipping disabled interface: {}", id); + return; + } + + // Pass cached details from getAllIds to getDetails to avoid additional dumps + final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, ifaceName, + index, ctx.getModificationCache(), LOG); + LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface); + + if (!isRegularInterface(iface)) { + LOG.debug("Interface: {} is a sub-interface. Ignoring read request.", ifaceName); + return; + } + + builder.setName(ifaceName); + builder.setType(getInterfaceType(new String(iface.interfaceName).intern())); + builder.setIfIndex(vppIfIndexToYang(iface.swIfIndex)); + builder.setAdminStatus(1 == iface.adminUpDown + ? AdminStatus.Up + : AdminStatus.Down); + builder.setOperStatus(1 == iface.linkUpDown + ? OperStatus.Up + : OperStatus.Down); + if (0 != iface.linkSpeed) { + builder.setSpeed(vppInterfaceSpeedToYang(iface.linkSpeed)); + } + if (iface.l2AddressLength == 6) { + builder.setPhysAddress(new PhysAddress(vppPhysAddrToYang(iface.l2Address))); + } + LOG.trace("Base attributes read for interface: {} as: {}", ifaceName, builder); + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext context) throws ReadFailedException { + final List interfacesKeys; + LOG.trace("Dumping all interfaces to get all IDs"); + + final SwInterfaceDump request = new SwInterfaceDump(); + request.nameFilter = "".getBytes(); + request.nameFilterValid = 0; + + final CompletableFuture swInterfaceDetailsReplyDumpCompletableFuture = + getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); + final SwInterfaceDetailsReplyDump ifaces = + getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); + + if (null == ifaces || null == ifaces.swInterfaceDetails) { + LOG.debug("No interfaces for :{} found in VPP", id); + return Collections.emptyList(); + } + + // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes + cacheInterfaceDump(context, ifaces); + + final MappingContext mappingCtx = context.getMappingContext(); + final Set interfacesIdxs = ifaces.swInterfaceDetails.stream() + .filter(elt -> elt != null) + // Filter out disabled interfaces, dont read them + // This also prevents child readers in being invoked such as vxlan (which relies on disabling interfaces) + .filter(elt -> !interfaceDisableContext + .isInterfaceDisabled(elt.swIfIndex, mappingCtx)) + .map((elt) -> { + // Store interface name from VPP in context if not yet present + if (!interfaceNamingContext.containsName(elt.swIfIndex, mappingCtx)) { + interfaceNamingContext.addName(elt.swIfIndex, toString(elt.interfaceName), + mappingCtx); + } + LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP", + interfaceNamingContext.getName(elt.swIfIndex, mappingCtx), + elt.interfaceName, + elt.swIfIndex); + + return elt; + }) + // filter out sub-interfaces + .filter(InterfaceCustomizer::isRegularInterface) + .map(elt -> elt.swIfIndex) + .collect(Collectors.toSet()); + + // Clean disabled interfaces list + interfaceDisableContext.getDisabledInterfaces(mappingCtx).stream() + // Find indices not currently in VPP + .filter(interfacesIdxs::contains) + // Remove from disabled list ... not disabled if not existing + .forEach(idx -> interfaceDisableContext.removeDisabledInterface(idx, mappingCtx)); + + // Transform indices to keys + interfacesKeys = interfacesIdxs.stream() + .map(index -> new InterfaceKey(interfaceNamingContext.getName(index, context.getMappingContext()))) + .collect(Collectors.toList()); + + LOG.debug("Interfaces found in VPP: {}", interfacesKeys); + return interfacesKeys; + } + + @Override + public void merge(@Nonnull final org.opendaylight.yangtools.concepts.Builder builder, + @Nonnull final List readData) { + ((InterfacesStateBuilder) builder).setInterface(readData); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final Interface readValue, @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder() + .setName(readValue.getName()) + .setType(readValue.getType()) + .setEnabled(AdminStatus.Up.equals(readValue.getAdminStatus())) + // Not present in interfaces-state + // .setLinkUpDownTrapEnable() + .build()); + } + + public static InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InstanceIdentifier.create(Interfaces.class).child( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface.class, + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey( + id.firstKeyOf(Interface.class).getName())); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java new file mode 100644 index 000000000..a0d292a4f --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java @@ -0,0 +1,287 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; + +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.math.BigInteger; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CompletionStage; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Gauge64; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.GreTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Loopback; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; + +public interface InterfaceDataTranslator extends ByteDataTranslator, JvppReplyConsumer { + + Gauge64 vppLinkSpeed0 = new Gauge64(BigInteger.ZERO); + Gauge64 vppLinkSpeed1 = new Gauge64(BigInteger.valueOf(10L * 1000000)); + Gauge64 vppLinkSpeed2 = new Gauge64(BigInteger.valueOf(100L * 1000000)); + Gauge64 vppLinkSpeed4 = new Gauge64(BigInteger.valueOf(1000L * 1000000)); + Gauge64 vppLinkSpeed8 = new Gauge64(BigInteger.valueOf(10000L * 1000000)); + Gauge64 vppLinkSpeed16 = new Gauge64(BigInteger.valueOf(40000L * 1000000)); + Gauge64 vppLinkSpeed32 = new Gauge64(BigInteger.valueOf(100000L * 1000000)); + + char[] HEX_CHARS = "0123456789abcdef".toCharArray(); + + int PHYSICAL_ADDRESS_LENGTH = 6; + + Collector SINGLE_ITEM_COLLECTOR = + RWUtils.singleItemCollector(); + + /** + * Convert VPP's link speed bitmask to Yang type. 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G + * + * @param vppLinkSpeed Link speed in bitmask format from VPP. + * @return Converted value from VPP link speed + */ + default Gauge64 vppInterfaceSpeedToYang(byte vppLinkSpeed) { + switch (vppLinkSpeed) { + case 1: + return vppLinkSpeed1; + case 2: + return vppLinkSpeed2; + case 4: + return vppLinkSpeed4; + case 8: + return vppLinkSpeed8; + case 16: + return vppLinkSpeed16; + case 32: + return vppLinkSpeed32; + default: + return vppLinkSpeed0; + } + } + + default void appendHexByte(final StringBuilder sb, final byte b) { + final int v = b & 0xFF; + sb.append(HEX_CHARS[v >>> 4]); + sb.append(HEX_CHARS[v & 15]); + } + + /** + * Reads first 6 bytes of supplied byte array and converts to string as Yang dictates

Replace later with + * https://git.opendaylight.org/gerrit/#/c/34869/10/model/ietf/ietf-type- util/src/main/ + * java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java + * + * @param vppPhysAddress byte array of bytes in big endian order, constructing the network IF physical address. + * @return String like "aa:bb:cc:dd:ee:ff" + * @throws NullPointerException if vppPhysAddress is null + * @throws IllegalArgumentException if vppPhysAddress.length < 6 + */ + default String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) { + return vppPhysAddrToYang(vppPhysAddress, 0); + } + + default String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress, final int startIndex) { + Objects.requireNonNull(vppPhysAddress, "Empty physical address bytes"); + final int endIndex = startIndex + PHYSICAL_ADDRESS_LENGTH; + checkArgument(endIndex <= vppPhysAddress.length, + "Invalid physical address size (%s) for given startIndex (%s), expected >= %s", vppPhysAddress.length, + startIndex, endIndex); + return printHexBinary(vppPhysAddress, startIndex, endIndex); + } + + default String printHexBinary(@Nonnull final byte[] bytes) { + Objects.requireNonNull(bytes, "bytes array should not be null"); + return printHexBinary(bytes, 0, bytes.length); + } + + default String printHexBinary(@Nonnull final byte[] bytes, final int startIndex, final int endIndex) { + StringBuilder str = new StringBuilder(); + + appendHexByte(str, bytes[startIndex]); + for (int i = startIndex + 1; i < endIndex; i++) { + str.append(":"); + appendHexByte(str, bytes[i]); + } + + return str.toString(); + } + + /** + * VPP's interface index is counted from 0, whereas ietf-interface's if-index is from 1. This function converts from + * VPP's interface index to YANG's interface index. + * + * @param vppIfIndex the sw interface index VPP reported. + * @return VPP's interface index incremented by one + */ + default int vppIfIndexToYang(int vppIfIndex) { + return vppIfIndex + 1; + } + + /** + * This function does the opposite of what {@link #vppIfIndexToYang(int)} does. + * + * @param yangIfIndex if-index from ietf-interfaces. + * @return VPP's representation of the if-index + */ + default int yangIfIndexToVpp(int yangIfIndex) { + checkArgument(yangIfIndex >= 1, "YANG if-index has invalid value %s", yangIfIndex); + return yangIfIndex - 1; + } + + + /** + * Queries VPP for interface description given interface key. + * + * @param futureJVppCore VPP Java Future API + * @param id InstanceIdentifier, which is passed in ReadFailedException + * @param name interface name + * @param index VPP index of the interface + * @param ctx per-tx scope context containing cached dump with all the interfaces. If the cache is not + * available or outdated, another dump will be performed. + * @return SwInterfaceDetails DTO or null if interface was not found + * @throws IllegalArgumentException If interface cannot be found + * @throws ReadFailedException If read operation had failed + */ + @Nonnull + default SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final InstanceIdentifier id, + @Nonnull final String name, final int index, + @Nonnull final ModificationCache ctx, + @Nonnull final Logger callerLogger) + throws ReadFailedException { + requireNonNull(futureJVppCore, "futureJVppCore should not be null"); + requireNonNull(name, "name should not be null"); + requireNonNull(ctx, "ctx should not be null"); + + final SwInterfaceDump request = new SwInterfaceDump(); + request.nameFilter = name.getBytes(); + request.nameFilterValid = 1; + + final Map allInterfaces = InterfaceCustomizer.getCachedInterfaceDump(ctx); + + // Returned cached if available + if (allInterfaces.containsKey(index)) { + return allInterfaces.get(index); + } + + SwInterfaceDetailsReplyDump ifaces; + + CompletionStage requestFuture = futureJVppCore.swInterfaceDump(request); + ifaces = getReplyForRead(requestFuture.toCompletableFuture(), id); + if (null == ifaces || null == ifaces.swInterfaceDetails || ifaces.swInterfaceDetails.isEmpty()) { + request.nameFilterValid = 0; + + callerLogger.warn("VPP returned null instead of interface by key {} and its not cached", name); + callerLogger.warn("Iterating through all the interfaces to find interface: {}", name); + + // Or else just perform full dump and do inefficient filtering + requestFuture = futureJVppCore.swInterfaceDump(request); + ifaces = getReplyForRead(requestFuture.toCompletableFuture(), id); + + // Update the cache + allInterfaces.clear(); + allInterfaces + .putAll(ifaces.swInterfaceDetails.stream().collect(Collectors.toMap(d -> d.swIfIndex, d -> d))); + + if (allInterfaces.containsKey(index)) { + return allInterfaces.get(index); + } + throw new IllegalArgumentException("Unable to find interface " + name); + } + + // SwInterfaceDump's name filter does prefix match, so we need additional filtering: + final SwInterfaceDetails iface = + ifaces.swInterfaceDetails.stream().filter(d -> d.swIfIndex == index).collect(SINGLE_ITEM_COLLECTOR); + allInterfaces.put(index, iface); // update the cache + return iface; + } + + /** + * Determine interface type based on its VPP name (relying on VPP's interface naming conventions) + * + * @param interfaceName VPP generated interface name + * @return Interface type + */ + @Nonnull + default Class getInterfaceType(@Nonnull final String interfaceName) { + if (interfaceName.startsWith("tap")) { + return Tap.class; + } + + if (interfaceName.startsWith("vxlan_gpe")) { + return VxlanGpeTunnel.class; + } + + if (interfaceName.startsWith("vxlan")) { + return VxlanTunnel.class; + } + + if (interfaceName.startsWith("gre")) { + return GreTunnel.class; + } + + if (interfaceName.startsWith("VirtualEthernet")) { + return VhostUser.class; + } + + if (interfaceName.startsWith("loop")) { + return Loopback.class; + } + + return EthernetCsmacd.class; + } + + /** + * Check interface type. Uses interface details from VPP to determine. Uses {@link + * #getVppInterfaceDetails(FutureJVppCore, InstanceIdentifier, String, int, ModificationCache, Logger)} internally + * so tries to utilize cache before asking VPP. + */ + default boolean isInterfaceOfType(@Nonnull final FutureJVppCore jvpp, + @Nonnull final ModificationCache cache, + @Nonnull final InstanceIdentifier id, + final int index, + @Nonnull final Class ifcType, + @Nonnull final Logger callerLogger) + throws ReadFailedException { + final String name = id.firstKeyOf(Interface.class).getName(); + final SwInterfaceDetails vppInterfaceDetails = + getVppInterfaceDetails(jvpp, id, name, index, cache, callerLogger); + + return isInterfaceOfType(ifcType, vppInterfaceDetails); + } + + default boolean isInterfaceOfType(final Class ifcType, + final SwInterfaceDetails cachedDetails) { + return ifcType.equals(getInterfaceType(toString(cachedDetails.interfaceName))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java new file mode 100644 index 000000000..ed88370f5 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.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.interfacesstate; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBased; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBased; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBasedBuilder; +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; + +/** + * Customizer for reading ietf-interfaces:interfaces-state/interface/iface_name/v3po:l2 + */ +public class L2Customizer extends FutureJVppCustomizer implements InitializingReaderCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class); + private final InterconnectionReadUtils icReadUtils; + + public L2Customizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext bridgeDomainContext) { + super(futureJVppCore); + this.icReadUtils = new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final L2 readValue) { + ((VppInterfaceStateAugmentationBuilder) parentBuilder).setL2(readValue); + } + + @Nonnull + @Override + public L2Builder getBuilder(@Nonnull final InstanceIdentifier id) { + return new L2Builder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2Builder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + + LOG.debug("Reading attributes for L2: {}", id); + final InterfaceKey key = id.firstKeyOf(Interface.class); + final String ifaceName = key.getName(); + builder.setInterconnection(icReadUtils.readInterconnection(id, ifaceName, ctx)); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final L2 readValue, + @Nonnull final ReadContext ctx) { + final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder + l2Builder = + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder(); + + final Interconnection interconnection = readValue.getInterconnection(); + if (interconnection != null) { + if (interconnection instanceof XconnectBased) { + final XconnectBasedBuilder xconnectBasedBuilder = new XconnectBasedBuilder(); + xconnectBasedBuilder.setXconnectOutgoingInterface( + ((XconnectBased) interconnection).getXconnectOutgoingInterface()); + l2Builder.setInterconnection(xconnectBasedBuilder.build()); + } else if (interconnection instanceof BridgeBased) { + final BridgeBasedBuilder bridgeBasedBuilder = new BridgeBasedBuilder(); + bridgeBasedBuilder.setBridgeDomain(((BridgeBased) interconnection).getBridgeDomain()); + bridgeBasedBuilder + .setBridgedVirtualInterface(((BridgeBased) interconnection).isBridgedVirtualInterface()); + bridgeBasedBuilder.setSplitHorizonGroup(((BridgeBased) interconnection).getSplitHorizonGroup()); + l2Builder.setInterconnection(bridgeBasedBuilder.build()); + } + } + + return Initialized.create(getCfgId(id), l2Builder.build()); + } + + private InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAugmentation.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java new file mode 100644 index 000000000..028e8e0d8 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java @@ -0,0 +1,79 @@ +/* + * 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; + +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.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArp; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProxyArpCustomizer extends FutureJVppCustomizer + implements ReaderCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class); + private final NamingContext interfaceContext; + + public ProxyArpCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { + super(vppApi); + this.interfaceContext = interfaceContext; + } + + @Override + public void merge(@Nonnull Builder parentBuilder, + @Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214 + .interfaces.state._interface.ProxyArp readValue) { + + ((VppInterfaceStateAugmentationBuilder) parentBuilder).setProxyArp(readValue); + } + + @Nonnull + @Override + public org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state + ._interface.ProxyArpBuilder getBuilder( + @Nonnull InstanceIdentifier id) { + + return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces + .state._interface.ProxyArpBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull InstanceIdentifier id, + @Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po + .rev161214.interfaces.state._interface.ProxyArpBuilder builder, + @Nonnull ReadContext ctx) throws ReadFailedException { + + //TODO: VPP-225 Implement fully when VPP Proxy ARP read API is available + add initializing + final InterfaceKey key = id.firstKeyOf(Interface.class); + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + LOG.warn("Reading of ARP data not (yet) supported by VPP API"); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java new file mode 100644 index 000000000..6906ebc0c --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java @@ -0,0 +1,147 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Preconditions; +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.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.hc2vpp.common.translate.util.TagRewriteOperation; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qTagVlanType; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTagBuilder; +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.vpp.vlan.rev161214._802dot1ad; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1q; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.RewriteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTagsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTagsKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for reading vlan tag-rewrite configuration state form the VPP. + */ +public class RewriteCustomizer extends FutureJVppCustomizer + implements ReaderCustomizer, InterfaceDataTranslator { + + // No initialization necessary since its parent Subinterface L2 customzier sets the entire subtree during + // initialization + + private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class); + private final NamingContext interfaceContext; + + public RewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, + @Nonnull final Rewrite readValue) { + ((L2Builder) parentBuilder).setRewrite(readValue); + } + + @Nonnull + @Override + public RewriteBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new RewriteBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final RewriteBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + final String subInterfaceName = getSubInterfaceName(id); + LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); + + final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, + interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache(), LOG); + LOG.debug("VPP sub-interface details: {}", iface); + + checkState(iface.subId != 0, "Interface returned by the VPP is not a sub-interface"); + + final TagRewriteOperation operation = TagRewriteOperation.get(iface.vtrOp); + if (TagRewriteOperation.disabled == operation) { + LOG.debug("Tag rewrite operation is disabled for "); + return; + } + + builder.setVlanType(iface.vtrPushDot1Q == 1 + ? _802dot1q.class + : _802dot1ad.class); + + setPushTags(builder, iface); + setPopTags(builder, operation); + } + + private static String getSubInterfaceName(final InstanceIdentifier id) { + return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), + Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier())); + } + + private void setPopTags(final RewriteBuilder builder, final TagRewriteOperation operation) { + final byte numberOfTagsToPop = operation.getPopTags(); + if (numberOfTagsToPop != 0) { + builder.setPopTags(Short.valueOf(numberOfTagsToPop)); + } + } + + private void setPushTags(final RewriteBuilder builder, final SwInterfaceDetails iface) { + final List tags = new ArrayList<>(); + if (iface.vtrTag1 != 0) { + tags.add(buildTag((short) 0, SVlan.class, iface.vtrTag1)); + } + if (iface.vtrTag2 != 0) { + tags.add(buildTag((short) 1, CVlan.class, iface.vtrTag2)); + } + if (tags.size() > 0) { + builder.setPushTags(tags); + } + } + + private PushTags buildTag(final short index, final Class tagType, final int vlanId) { + final PushTagsBuilder tag = new PushTagsBuilder(); + tag.setIndex(index); + tag.setKey(new PushTagsKey(index)); + final Dot1qTagBuilder dtag = new Dot1qTagBuilder(); + dtag.setTagType(tagType); + dtag.setVlanId(new Dot1qVlanId(vlanId)); + tag.setDot1qTag(dtag.build()); + return tag.build(); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java new file mode 100644 index 000000000..9c13b382a --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java @@ -0,0 +1,264 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Preconditions; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qTagVlanType; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan; +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.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTagBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubInterfaceStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfacesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.DefaultBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.UntaggedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTaggedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.TagsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagKey; +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; + +/** + * Customizer for reading sub interfaces form the VPP. + */ +public class SubInterfaceCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, ByteDataTranslator, + InterfaceDataTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class); + private static final Dot1qTag.VlanId ANY_VLAN_ID = new Dot1qTag.VlanId(Dot1qTag.VlanId.Enumeration.Any); + private NamingContext interfaceContext; + + public SubInterfaceCustomizer(@Nonnull final FutureJVppCore jvpp, + @Nonnull final NamingContext interfaceContext) { + super(jvpp); + this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + private static String getSubInterfaceName(final InstanceIdentifier id) { + return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), + Math.toIntExact(id.firstKeyOf(id.getTargetType()).getIdentifier())); + } + + private static Tag buildTag(final short index, final Class tagType, + final Dot1qTag.VlanId vlanId) { + TagBuilder tag = new TagBuilder(); + tag.setIndex(index); + tag.setKey(new TagKey(index)); + final Dot1qTagBuilder dtag = new Dot1qTagBuilder(); + dtag.setTagType(tagType); + dtag.setVlanId(vlanId); + tag.setDot1qTag(dtag.build()); + return tag.build(); + } + + private static Dot1qTag.VlanId buildVlanId(final short vlanId) { + // treat vlanId as unsigned value: + return new Dot1qTag.VlanId(new Dot1qVlanId(0xffff & vlanId)); + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext context) throws ReadFailedException { + // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) + // to fill in the context with initial ifc mapping + final InterfaceKey key = id.firstKeyOf(Interface.class); + final String ifaceName = key.getName(); + final int ifaceId = interfaceContext.getIndex(ifaceName, context.getMappingContext()); + + // TODO HONEYCOMB-189 if we know that full dump was already performed we could use cache + // (checking if getCachedInterfaceDump() returns non empty map is not enough, because + // we could be part of particular iface state read + final SwInterfaceDump request = new SwInterfaceDump(); + request.nameFilter = "".getBytes(); + request.nameFilterValid = 0; + + final CompletableFuture swInterfaceDetailsReplyDumpCompletableFuture = + getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); + final SwInterfaceDetailsReplyDump ifaces = + getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); + + if (null == ifaces || null == ifaces.swInterfaceDetails) { + LOG.warn("Looking for sub-interfaces, but no interfaces found in VPP"); + return Collections.emptyList(); + } + + // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes + context.getModificationCache() + .put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); + + final List interfacesKeys = ifaces.swInterfaceDetails.stream() + .filter(elt -> elt != null) + // accept only sub-interfaces for current iface: + .filter(elt -> elt.subId != 0 && elt.supSwIfIndex == ifaceId) + .map(details -> new SubInterfaceKey(new Long(details.subId))) + .collect(Collectors.toList()); + + LOG.debug("Sub-interfaces of {} found in VPP: {}", ifaceName, interfacesKeys); + return interfacesKeys; + } + + @Override + public void merge(@Nonnull final Builder builder, + @Nonnull final List readData) { + ((SubInterfacesBuilder) builder).setSubInterface(readData); + } + + @Nonnull + @Override + public SubInterfaceBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new SubInterfaceBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final SubInterfaceBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + final String subInterfaceName = getSubInterfaceName(id); + LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); + + final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, + interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache(), LOG); + LOG.debug("VPP sub-interface details: {}", iface); + + checkState(iface.subId != 0, "Interface returned by the VPP is not a sub-interface"); + + builder.setIdentifier(Long.valueOf(iface.subId)); + builder.setKey(new SubInterfaceKey(builder.getIdentifier())); + + // sub-interface-base-attributes: + builder.setTags(readTags(iface)); + builder.setMatch(readMatch(iface)); + + // sub-interface-operational-attributes: + builder.setAdminStatus(1 == iface.adminUpDown + ? SubInterfaceStatus.Up + : SubInterfaceStatus.Down); + builder.setOperStatus(1 == iface.linkUpDown + ? SubInterfaceStatus.Up + : SubInterfaceStatus.Down); + builder.setIfIndex(vppIfIndexToYang(iface.swIfIndex)); + if (iface.l2AddressLength == 6) { + builder.setPhysAddress(new PhysAddress(vppPhysAddrToYang(iface.l2Address))); + } + if (0 != iface.linkSpeed) { + builder.setSpeed(vppInterfaceSpeedToYang(iface.linkSpeed)); + } + } + + private Tags readTags(final SwInterfaceDetails iface) { + final TagsBuilder tags = new TagsBuilder(); + final List list = new ArrayList<>(); + if (iface.subNumberOfTags > 0) { + if (iface.subOuterVlanIdAny == 1) { + list.add(buildTag((short) 0, SVlan.class, ANY_VLAN_ID)); + } else { + list.add(buildTag((short) 0, SVlan.class, buildVlanId(iface.subOuterVlanId))); + } + // inner tag (customer tag): + if (iface.subNumberOfTags == 2) { + if (iface.subInnerVlanIdAny == 1) { + list.add(buildTag((short) 1, CVlan.class, ANY_VLAN_ID)); + } else { + list.add(buildTag((short) 1, CVlan.class, buildVlanId(iface.subInnerVlanId))); + } + } + } + tags.setTag(list); + return tags.build(); + } + + private Match readMatch(final SwInterfaceDetails iface) { + final MatchBuilder match = new MatchBuilder(); + if (iface.subDefault == 1) { + match.setMatchType(new DefaultBuilder().build()); + } else if (iface.subNumberOfTags == 0) { + match.setMatchType(new UntaggedBuilder().build()); + } else { + final VlanTaggedBuilder tagged = new VlanTaggedBuilder(); + tagged.setMatchExactTags(byteToBoolean(iface.subExactMatch)); + match.setMatchType( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.VlanTaggedBuilder() + .setVlanTagged(tagged.build()).build()); + } + return match.build(); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final SubInterface readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder() + .setEnabled(SubInterfaceStatus.Up.equals(readValue.getAdminStatus())) + .setIdentifier(readValue.getIdentifier()) + .setMatch(readValue.getMatch()) + .setTags(readValue.getTags()) + .setVlanType(readValue.getVlanType()) + .build()); + } + + public static InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(SubinterfaceAugmentation.class) + .child(SubInterfaces.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey( + id.firstKeyOf(SubInterface.class).getIdentifier())); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java new file mode 100644 index 000000000..1b98b41ef --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java @@ -0,0 +1,93 @@ +/* + * 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; + +import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; +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; + +/** + * Customizer for reading vlan sub interface L2 operational state + */ +public class SubInterfaceL2Customizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class); + private final InterconnectionReadUtils icReadUtils; + + public SubInterfaceL2Customizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext bridgeDomainContext) { + super(futureJVppCore); + this.icReadUtils = new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final L2 readValue) { + ((SubInterfaceBuilder) parentBuilder).setL2(readValue); + } + + @Nonnull + @Override + public L2Builder getBuilder(@Nonnull final InstanceIdentifier id) { + return new L2Builder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2Builder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading attributes for sub-interface L2: {}", id); + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + final String subInterfaceName = getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + + builder.setInterconnection(icReadUtils.readInterconnection(id, subInterfaceName, ctx)); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final L2 readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), readValue); + } + + static InstanceIdentifier getCfgId(final InstanceIdentifier id) { + return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) + .child(L2.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java new file mode 100644 index 000000000..683450da3 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java @@ -0,0 +1,143 @@ +/* + * 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; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionStage; +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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Tap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.TapBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class TapCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class); + public static final String DUMPED_TAPS_CONTEXT_KEY = TapCustomizer.class.getName() + "dumpedTapsDuringGetAllIds"; + private NamingContext interfaceContext; + + public TapCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + super(jvpp); + this.interfaceContext = interfaceContext; + } + + @Override + public void merge(@Nonnull Builder parentBuilder, @Nonnull Tap readValue) { + ((VppInterfaceStateAugmentationBuilder) parentBuilder).setTap(readValue); + } + + @Nonnull + @Override + public TapBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new TapBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final TapBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + + final InterfaceKey key = id.firstKeyOf(Interface.class); + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap.class, LOG)) { + return; + } + + LOG.debug("Reading attributes for tap interface: {}", key.getName()); + + @SuppressWarnings("unchecked") + Map mappedTaps = + (Map) ctx.getModificationCache().get(DUMPED_TAPS_CONTEXT_KEY); + + if (mappedTaps == null) { + // Full Tap dump has to be performed here, no filter or anything is here to help so at least we cache it + final SwInterfaceTapDump request = new SwInterfaceTapDump(); + final CompletionStage swInterfaceTapDetailsReplyDumpCompletionStage = + getFutureJVpp().swInterfaceTapDump(request); + final SwInterfaceTapDetailsReplyDump reply = + getReplyForRead(swInterfaceTapDetailsReplyDumpCompletionStage.toCompletableFuture(), id); + + if (null == reply || null == reply.swInterfaceTapDetails) { + mappedTaps = Collections.emptyMap(); + } else { + final List swInterfaceTapDetails = reply.swInterfaceTapDetails; + // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes + mappedTaps = swInterfaceTapDetails.stream() + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); + } + + ctx.getModificationCache().put(DUMPED_TAPS_CONTEXT_KEY, mappedTaps); + } + + final SwInterfaceTapDetails swInterfaceTapDetails = mappedTaps.get(index); + LOG.trace("Tap interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceTapDetails); + + builder.setTapName(toString(swInterfaceTapDetails.devName)); + LOG.debug("Tap interface: {}, id: {} attributes read as: {}", key.getName(), index, builder); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final Tap readValue, @Nonnull final ReadContext ctx) { + // The MAC address is set from interface details, those details are retrieved from cache + final InterfaceKey key = id.firstKeyOf(Interface.class); + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + final SwInterfaceDetails ifcDetails = + InterfaceCustomizer.getCachedInterfaceDump(ctx.getModificationCache()).get(index); + + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.TapBuilder() + .setMac(new PhysAddress(vppPhysAddrToYang(ifcDetails.l2Address))) + .setTapName(readValue.getTapName()) +// tapBuilder.setDeviceInstance(); + .build()); + } + + private InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAugmentation.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java new file mode 100644 index 000000000..6a918e842 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java @@ -0,0 +1,154 @@ +/* + * 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; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.math.BigInteger; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionStage; +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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUserRole; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUser; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUserBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class VhostUserCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { + + public static final String DUMPED_VHOST_USERS_CONTEXT_KEY = + VhostUserCustomizer.class.getName() + "dumpedVhostUsersDuringGetAllIds"; + private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class); + private NamingContext interfaceContext; + + public VhostUserCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + super(jvpp); + this.interfaceContext = interfaceContext; + } + + @Override + public void merge(@Nonnull Builder parentBuilder, @Nonnull VhostUser readValue) { + ((VppInterfaceStateAugmentationBuilder) parentBuilder).setVhostUser(readValue); + } + + @Nonnull + @Override + public VhostUserBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new VhostUserBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final VhostUserBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + + final InterfaceKey key = id.firstKeyOf(Interface.class); + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser.class, + LOG)) { + return; + } + + LOG.debug("Reading attributes for vhpost user interface: {}", key.getName()); + + @SuppressWarnings("unchecked") + Map mappedVhostUsers = + (Map) ctx.getModificationCache() + .get(DUMPED_VHOST_USERS_CONTEXT_KEY); + + if (mappedVhostUsers == null) { + // Full VhostUser dump has to be performed here, no filter or anything is here to help so at least we cache it + final SwInterfaceVhostUserDump request = new SwInterfaceVhostUserDump(); + final CompletionStage + swInterfaceVhostUserDetailsReplyDumpCompletionStage = + getFutureJVpp().swInterfaceVhostUserDump(request); + final SwInterfaceVhostUserDetailsReplyDump reply = + getReplyForRead(swInterfaceVhostUserDetailsReplyDumpCompletionStage.toCompletableFuture(), id); + + if (null == reply || null == reply.swInterfaceVhostUserDetails) { + mappedVhostUsers = Collections.emptyMap(); + } else { + final List swInterfaceVhostUserDetails = + reply.swInterfaceVhostUserDetails; + // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes + mappedVhostUsers = swInterfaceVhostUserDetails.stream() + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); + } + + ctx.getModificationCache().put(DUMPED_VHOST_USERS_CONTEXT_KEY, mappedVhostUsers); + } + + // Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping + final SwInterfaceVhostUserDetails swInterfaceVhostUserDetails = mappedVhostUsers.get(index); + LOG.trace("Vhost user interface: {} attributes returned from VPP: {}", key.getName(), + swInterfaceVhostUserDetails); + + builder.setRole(swInterfaceVhostUserDetails.isServer == 1 + ? VhostUserRole.Server + : VhostUserRole.Client); + builder.setFeatures(BigInteger.valueOf(swInterfaceVhostUserDetails.features)); + builder.setNumMemoryRegions((long) swInterfaceVhostUserDetails.numRegions); + builder.setSocket(toString(swInterfaceVhostUserDetails.sockFilename)); + builder.setVirtioNetHdrSize((long) swInterfaceVhostUserDetails.virtioNetHdrSz); + // TODO: map error code to meaningful message after VPP-436 is done + builder.setConnectError(Integer.toString(swInterfaceVhostUserDetails.sockErrno)); + + LOG.debug("Vhost user interface: {}, id: {} attributes read as: {}", key.getName(), index, builder); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final VhostUser readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUserBuilder() + .setRole(readValue.getRole()) + .setSocket(readValue.getSocket()) + .build()); + } + + private InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAugmentation.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java new file mode 100644 index 000000000..d3174e643 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java @@ -0,0 +1,162 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkState; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetails; +import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.VxlanTunnelDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanVni; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Vxlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VxlanCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class); + private final NamingContext interfaceContext; + + public VxlanCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + super(jvpp); + this.interfaceContext = interfaceContext; + } + + @Override + public void merge(@Nonnull Builder parentBuilder, + @Nonnull Vxlan readValue) { + ((VppInterfaceStateAugmentationBuilder) parentBuilder).setVxlan(readValue); + } + + @Nonnull + @Override + public VxlanBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new VxlanBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final VxlanBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + + final InterfaceKey key = id.firstKeyOf(Interface.class); + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanTunnel.class, LOG)) { + return; + } + + LOG.debug("Reading attributes for vxlan tunnel: {}", key.getName()); + // Dump just a single + final VxlanTunnelDump request = new VxlanTunnelDump(); + request.swIfIndex = index; + + final CompletionStage swInterfaceVxlanDetailsReplyDumpCompletionStage = + getFutureJVpp().vxlanTunnelDump(request); + final VxlanTunnelDetailsReplyDump reply = + getReplyForRead(swInterfaceVxlanDetailsReplyDumpCompletionStage.toCompletableFuture(), id); + + // VPP keeps vxlan tunnel interfaces even after they were deleted (optimization) + // However there ar no longer any vxlan tunnel specific fields assigned to it and this call + // returns nothing + if (reply == null || reply.vxlanTunnelDetails == null || reply.vxlanTunnelDetails.isEmpty()) { + LOG.debug( + "Vxlan tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + + "after delete", key.getName(), index); + return; + } + + checkState(reply.vxlanTunnelDetails.size() == 1, + "Unexpected number of returned vxlan tunnels: {} for tunnel: {}", reply.vxlanTunnelDetails, + key.getName()); + LOG.trace("Vxlan tunnel: {} attributes returned from VPP: {}", key.getName(), reply); + + final VxlanTunnelDetails swInterfaceVxlanDetails = reply.vxlanTunnelDetails.get(0); + if (swInterfaceVxlanDetails.isIpv6 == 1) { + final Ipv6Address dstIpv6 = + new Ipv6Address(parseAddress(swInterfaceVxlanDetails.dstAddress).getHostAddress()); + builder.setDst(new IpAddress(dstIpv6)); + final Ipv6Address srcIpv6 = + new Ipv6Address(parseAddress(swInterfaceVxlanDetails.srcAddress).getHostAddress()); + builder.setSrc(new IpAddress(srcIpv6)); + } else { + final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.dstAddress, 0, 4); + final Ipv4Address dstIpv4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); + builder.setDst(new IpAddress(dstIpv4)); + final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.srcAddress, 0, 4); + final Ipv4Address srcIpv4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); + builder.setSrc(new IpAddress(srcIpv4)); + } + builder.setEncapVrfId((long) swInterfaceVxlanDetails.encapVrfId); + builder.setVni(new VxlanVni((long) swInterfaceVxlanDetails.vni)); + LOG.debug("Vxlan tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); + } + + @Nonnull + private static InetAddress parseAddress(@Nonnull final byte[] addr) { + try { + return InetAddress.getByAddress(addr); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e); + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final Vxlan readValue, @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanBuilder() + .setDst(readValue.getDst()) + .setSrc(readValue.getSrc()) + .setEncapVrfId(readValue.getEncapVrfId()) + .setVni(new VxlanVni(readValue.getVni())) + .build()); + } + + private InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAugmentation.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java new file mode 100644 index 000000000..b10fef3e8 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java @@ -0,0 +1,168 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkState; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetails; +import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeNextProtocol; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeVni; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpe; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpeBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VxlanGpeCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class); + private NamingContext interfaceContext; + + public VxlanGpeCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + super(jvpp); + this.interfaceContext = interfaceContext; + } + + @Override + public void merge(@Nonnull Builder parentBuilder, + @Nonnull VxlanGpe readValue) { + ((VppInterfaceStateAugmentationBuilder) parentBuilder).setVxlanGpe(readValue); + } + + @Nonnull + @Override + public VxlanGpeBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new VxlanGpeBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final VxlanGpeBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + + final InterfaceKey key = id.firstKeyOf(Interface.class); + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanGpeTunnel.class, LOG)) { + return; + } + + LOG.debug("Reading attributes for VxlanGpe tunnel: {}", key.getName()); + // Dump just a single + final VxlanGpeTunnelDump request = new VxlanGpeTunnelDump(); + request.swIfIndex = index; + + final CompletionStage swInterfaceVxlanGpeDetailsReplyDumpCompletionStage = + getFutureJVpp().vxlanGpeTunnelDump(request); + final VxlanGpeTunnelDetailsReplyDump reply = + getReplyForRead(swInterfaceVxlanGpeDetailsReplyDumpCompletionStage.toCompletableFuture(), + id); + + // VPP keeps VxlanGpe tunnel interfaces even after they were deleted (optimization) + // However there are no longer any VxlanGpe tunnel specific fields assigned to it and this call + // returns nothing + if (reply == null || reply.vxlanGpeTunnelDetails == null || reply.vxlanGpeTunnelDetails.isEmpty()) { + LOG.debug( + "VxlanGpe tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + + "after delete", key.getName(), index); + return; + } + + checkState(reply.vxlanGpeTunnelDetails.size() == 1, + "Unexpected number of returned VxlanGpe tunnels: {} for tunnel: {}", reply.vxlanGpeTunnelDetails, + key.getName()); + LOG.trace("VxlanGpe tunnel: {} attributes returned from VPP: {}", key.getName(), reply); + + final VxlanGpeTunnelDetails swInterfaceVxlanGpeDetails = reply.vxlanGpeTunnelDetails.get(0); + if (swInterfaceVxlanGpeDetails.isIpv6 == 1) { + final Ipv6Address remote6 = + new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.remote).getHostAddress()); + builder.setRemote(new IpAddress(remote6)); + final Ipv6Address local6 = + new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.local).getHostAddress()); + builder.setLocal(new IpAddress(local6)); + } else { + final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.remote, 0, 4); + final Ipv4Address remote4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); + builder.setRemote(new IpAddress(remote4)); + final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.local, 0, 4); + final Ipv4Address local4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); + builder.setLocal(new IpAddress(local4)); + } + builder.setVni(new VxlanGpeVni((long) swInterfaceVxlanGpeDetails.vni)); + builder.setNextProtocol(VxlanGpeNextProtocol.forValue(swInterfaceVxlanGpeDetails.protocol)); + builder.setEncapVrfId((long) swInterfaceVxlanGpeDetails.encapVrfId); + builder.setDecapVrfId((long) swInterfaceVxlanGpeDetails.decapVrfId); + LOG.debug("VxlanGpe tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); + } + + @Nonnull + private static InetAddress parseAddress(@Nonnull final byte[] addr) { + try { + return InetAddress.getByAddress(addr); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e); + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final VxlanGpe readValue, @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpeBuilder() + .setLocal(readValue.getLocal()) + .setRemote(readValue.getRemote()) + .setVni(new VxlanGpeVni(readValue.getVni())) + .setNextProtocol(readValue.getNextProtocol()) + .setEncapVrfId(readValue.getEncapVrfId()) + .setDecapVrfId(readValue.getDecapVrfId()) + .build()); + } + + private InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAugmentation.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java new file mode 100644 index 000000000..713868d2e --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java @@ -0,0 +1,118 @@ +/* + * 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.acl.ingress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.IngressBuilder; +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; + +/** + * Customizer for reading ingress ACLs enabled on given interface. + */ +public class AclCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, AclReader, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class); + private final NamingContext interfaceContext; + private final VppClassifierContextManager classifyTableContext; + + public AclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(jvpp); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ingress readValue) { + ((AclBuilder) parentBuilder).setIngress(readValue); + } + + @Nonnull + @Override + public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new IngressBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final IngressBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading attributes for interface ACL: {}", id); + final InterfaceKey interfaceKey = id.firstKeyOf(Interface.class); + checkArgument(interfaceKey != null, "No parent interface key found"); + + final ClassifyTableByInterface request = new ClassifyTableByInterface(); + request.swIfIndex = interfaceContext.getIndex(interfaceKey.getName(), ctx.getMappingContext()); + + final ClassifyTableByInterfaceReply reply = + getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); + + builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext())); + builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext())); + builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext())); + + if (LOG.isTraceEnabled()) { + LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build()); + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final Ingress readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.IngressBuilder() + .setL2Acl(readValue.getL2Acl()) + .setIp4Acl(readValue.getIp4Acl()) + .setIp6Acl(readValue.getIp6Acl()) + .build()); + } + + private InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAugmentation.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java new file mode 100644 index 000000000..8f1b428b9 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java @@ -0,0 +1,60 @@ +/* + * 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.acl.ingress; + +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2AclBuilder; + +interface AclReader { + + @Nonnull + default L2Acl readL2Acl(final int l2TableId, @Nonnull final VppClassifierContextManager classifyTableContext, + @Nonnull final MappingContext mappingContext) { + if (l2TableId == ~0) { + return null; + } + return new L2AclBuilder() + .setClassifyTable(classifyTableContext.getTableName(l2TableId, mappingContext)).build(); + } + + @Nonnull + default Ip4Acl readIp4Acl(final int ip4TableId, @Nonnull final VppClassifierContextManager classifyTableContext, + @Nonnull final MappingContext mappingContext) { + if (ip4TableId == ~0) { + return null; + } + return new Ip4AclBuilder() + .setClassifyTable(classifyTableContext.getTableName(ip4TableId, mappingContext)).build(); + } + + @Nonnull + default Ip6Acl readIp6Acl(final int ip6TableId, @Nonnull final VppClassifierContextManager classifyTableContext, + @Nonnull final MappingContext mappingContext) { + if (ip6TableId == ~0) { + return null; + } + return new Ip6AclBuilder() + .setClassifyTable(classifyTableContext.getTableName(ip6TableId, mappingContext)).build(); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java new file mode 100644 index 000000000..4190619b8 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java @@ -0,0 +1,120 @@ +/* + * 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.acl.ingress; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName; + +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder; +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; + +/** + * Customizer for reading ingress ACLs enabled on given sub-interface. + */ +public class SubInterfaceAclCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer, AclReader, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class); + private final NamingContext interfaceContext; + private final VppClassifierContextManager classifyTableContext; + + public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(jvpp); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ingress readValue) { + ((AclBuilder) parentBuilder).setIngress(readValue); + } + + @Nonnull + @Override + public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new IngressBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final IngressBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading attributes for sub-interface ACL: {}", id); + final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); + checkArgument(parentInterfacekey != null, "No parent interface key found"); + final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); + checkArgument(subInterfacekey != null, "No sub-interface key found"); + final String subInterfaceName = + getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + + final ClassifyTableByInterface request = new ClassifyTableByInterface(); + request.swIfIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); + + final ClassifyTableByInterfaceReply reply = + getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); + + builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext())); + builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext())); + builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext())); + + if (LOG.isTraceEnabled()) { + LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build()); + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final Ingress readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), readValue); + } + + static InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) + .child(Acl.class) + .child(Ingress.class); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java new file mode 100644 index 000000000..4a577ae60 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java @@ -0,0 +1,166 @@ +/* + * 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.ip; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import com.google.common.base.Preconditions; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.AddressDumpParams; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.IpAddressDetails; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLengthBuilder; +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; + +/** + * Read customizer for interface Ipv4 addresses. + */ +public class Ipv4AddressCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, Ipv4Reader { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressCustomizer.class); + private static final String CACHE_KEY = Ipv4AddressCustomizer.class.getName(); + + private final NamingContext interfaceContext; + private final DumpCacheManager dumpManager; + + public Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(createExecutor(futureJVppCore)) + // Key needs to contain interface ID to distinguish dumps between interfaces + .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(Interface.class))) + .build(); + } + + @Override + @Nonnull + public AddressBuilder getBuilder(@Nonnull InstanceIdentifier

id) { + return new AddressBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull InstanceIdentifier
id, @Nonnull AddressBuilder builder, + @Nonnull ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes for interface address: {}", id); + + final String interfaceName = id.firstKeyOf(Interface.class).getName(); + final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); + final Optional dumpOptional = + dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); + + if (!dumpOptional.isPresent() || dumpOptional.get().ipAddressDetails.isEmpty()) { + return; + } + final Optional ipAddressDetails = + findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); + + if (ipAddressDetails.isPresent()) { + final IpAddressDetails detail = ipAddressDetails.get(); + builder.setIp(arrayToIpv4AddressNoZone(detail.ip)) + .setSubnet( + new PrefixLengthBuilder().setPrefixLength(Short.valueOf(detail.prefixLength)).build()); + + if (LOG.isDebugEnabled()) { + LOG.debug("Attributes for {} interface (id={}) address {} successfully read: {}", + interfaceName, interfaceIndex, id, builder.build()); + } + } + } + + @Override + public List getAllIds(@Nonnull InstanceIdentifier
id, @Nonnull ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading list of keys for interface addresses: {}", id); + + final String interfaceName = id.firstKeyOf(Interface.class).getName(); + final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); + final Optional dumpOptional = + dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); + + return getAllIpv4AddressIds(dumpOptional, AddressKey::new); + } + + @Override + public void merge(@Nonnull Builder builder, @Nonnull List
readData) { + ((Ipv4Builder) builder).setAddress(readData); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier
id, @Nonnull final Address readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder() + .setIp(readValue.getIp()) + .setSubnet(getSubnet(readValue)) + .build()); + } + + private static Subnet getSubnet(final Address address) { + final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.Subnet + subnet = address.getSubnet(); + + // Only prefix length supported + Preconditions.checkArgument( + subnet instanceof org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLength); + + return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder() + .setPrefixLength( + ((org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLength) subnet) + .getPrefixLength()).build(); + } + + static InstanceIdentifier getCfgId( + final InstanceIdentifier
id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(Interface1.class) + .child(Ipv4.class) + .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address.class, + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressKey(id.firstKeyOf(Address.class).getIp())); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java new file mode 100644 index 000000000..316f8ec47 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java @@ -0,0 +1,59 @@ +/* + * 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.ip; + +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.hc2vpp.common.translate.util.FutureJVppCustomizer; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Ipv4Customizer extends FutureJVppCustomizer implements ReaderCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class); + + public Ipv4Customizer(@Nonnull final FutureJVppCore futureJVppCore) { + super(futureJVppCore); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ipv4 readValue) { + ((Interface2Builder) parentBuilder).setIpv4(readValue); + } + + @Nonnull + @Override + public Ipv4Builder getBuilder(@Nonnull final InstanceIdentifier id) { + return new Ipv4Builder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ipv4Builder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading Ipv4 leaves (mtu, forwarding) is not supported by VPP API"); + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java new file mode 100644 index 000000000..a32f8f20c --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java @@ -0,0 +1,73 @@ +/* + * 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.ip; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborKey; +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; + +/** + * Operational data read operation customizer for {@link Neighbor}
+ * Currently not supported in jvpp, so this is only dummy implementation
+ */ +public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); + + public Ipv4NeighbourCustomizer(FutureJVppCore futureJVppCore) { + super(futureJVppCore); + } + + @Override + public NeighborBuilder getBuilder(InstanceIdentifier id) { + return new NeighborBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier id, NeighborBuilder builder, ReadContext ctx) + throws ReadFailedException { + //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first + implement init + LOG.warn("Operation not supported"); + } + + @Override + public List getAllIds(InstanceIdentifier id, ReadContext context) + throws ReadFailedException { + //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first + LOG.warn("Operation not supported,returning empty List"); + return Collections.emptyList(); + } + + @Override + public void merge(Builder builder, List readData) { + ((Ipv4Builder) builder).setNeighbor(readData); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java new file mode 100644 index 000000000..729ca097d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java @@ -0,0 +1,84 @@ +/* + * 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.ip; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.AddressDumpParams; +import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.IpAddressDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Collections; +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.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yangtools.yang.binding.Identifier; +import io.fd.vpp.jvpp.core.dto.IpAddressDetails; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; + +/** + * Utility class providing Ipv4 read support. + */ +interface Ipv4Reader extends Ipv4Translator, JvppReplyConsumer { + + @Nonnull + default List getAllIpv4AddressIds( + final Optional dumpOptional, + @Nonnull final Function keyConstructor) { + if (dumpOptional.isPresent() && dumpOptional.get().ipAddressDetails != null) { + return dumpOptional.get().ipAddressDetails.stream() + .map(detail -> keyConstructor.apply(arrayToIpv4AddressNoZone(detail.ip))) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + default Optional findIpAddressDetailsByIp( + final Optional dump, + @Nonnull final Ipv4AddressNoZone ip) { + checkNotNull(ip, "ip address should not be null"); + + if (dump.isPresent() && dump.get().ipAddressDetails != null) { + final List details = dump.get().ipAddressDetails; + + return Optional.of(details.stream() + .filter(singleDetail -> ip.equals(arrayToIpv4AddressNoZone(singleDetail.ip))) + .collect(RWUtils.singleItemCollector())); + } + return Optional.absent(); + } + + default EntityDumpExecutor createExecutor( + @Nonnull final FutureJVppCore vppApi) { + return (identifier, params) -> { + checkNotNull(params, "Address dump params cannot be null"); + + final IpAddressDump dumpRequest = new IpAddressDump(); + dumpRequest.isIpv6 = booleanToByte(params.isIpv6()); + dumpRequest.swIfIndex = params.getInterfaceIndex(); + + return getReplyForRead(vppApi.ipAddressDump(dumpRequest).toCompletableFuture(), identifier); + }; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java new file mode 100644 index 000000000..97f223a8c --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java @@ -0,0 +1,66 @@ +/* + * 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.ip; + +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.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6Builder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +public class Ipv6Customizer extends FutureJVppCustomizer implements ReaderCustomizer { + + private final NamingContext interfaceContext; + + public Ipv6Customizer(@Nonnull final FutureJVppCore futureJVppCore, final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = interfaceContext; + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ipv6 readValue) { + ((Interface2Builder) parentBuilder).setIpv6(readValue); + } + + @Nonnull + @Override + public Ipv6Builder getBuilder(@Nonnull final InstanceIdentifier id) { + return new Ipv6Builder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ipv6Builder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + // TODO HONEYCOMB-102 implement + init +// final IpAddressDump dumpRequest = new IpAddressDump(); +// dumpRequest.isIpv6 = 1; +// dumpRequest.swIfIndex = interfaceContext.getIndex(id.firstKeyOf(Interface.class).getName(), +// ctx.getMappingContext()); +// final CompletionStage addressDumpFuture = getFutureJVpp(). +// ipAddressDump(dumpRequest); +// final IpAddressDetailsReplyDump reply = TranslateUtils.getReply(addressDumpFuture.toCompletableFuture()); + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java new file mode 100644 index 000000000..eee49799b --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java @@ -0,0 +1,143 @@ +/* + * 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.ip; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.AddressDumpParams; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.vpp.jvpp.core.dto.IpAddressDetails; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +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.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder; +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; + +/** + * Read customizer for sub-interface Ipv4 addresses. + */ +public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, Ipv4Reader { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class); + + private final NamingContext interfaceContext; + private final DumpCacheManager dumpManager; + + public SubInterfaceIpv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(createExecutor(futureJVppCore)) + //same as with ipv4 addresses for interfaces, these must have cache scope of their parent sub-interface + .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(SubInterface.class))) + .build(); + } + + @Override + @Nonnull + public AddressBuilder getBuilder(@Nonnull InstanceIdentifier
id) { + return new AddressBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull InstanceIdentifier
id, @Nonnull AddressBuilder builder, + @Nonnull ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes for sub-interface address: {}", id); + + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); + final Optional dumpOptional = dumpManager + .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); + + final Optional ipAddressDetails = + findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); + + if (ipAddressDetails.isPresent()) { + final IpAddressDetails detail = ipAddressDetails.get(); + builder.setIp(arrayToIpv4AddressNoZone(detail.ip)); + builder.setSubnet(new PrefixLengthBuilder().setPrefixLength(Short.valueOf(detail.prefixLength)).build()); + + if (LOG.isDebugEnabled()) { + LOG.debug("Attributes for {} sub-interface (id={}) address {} successfully read: {}", + subInterfaceName, subInterfaceIndex, id, builder.build()); + } + } + } + + @Override + public List getAllIds(@Nonnull InstanceIdentifier
id, @Nonnull ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading list of keys for sub-interface addresses: {}", id); + + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); + final Optional dumpOptional = dumpManager + .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); + + return getAllIpv4AddressIds(dumpOptional, AddressKey::new); + } + + @Override + public void merge(@Nonnull Builder builder, @Nonnull List
readData) { + ((Ipv4Builder) builder).setAddress(readData); + } + + private static String getSubInterfaceName(@Nonnull final InstanceIdentifier
id) { + return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), + Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier())); + } + + @Override + public Initialized
init( + @Nonnull final InstanceIdentifier
id, @Nonnull final Address readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), readValue); + } + + private InstanceIdentifier
getCfgId(final InstanceIdentifier
id) { + return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) + .child(Ipv4.class) + .child(Address.class, new AddressKey(id.firstKeyOf(Address.class))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java new file mode 100644 index 000000000..cb80893be --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java @@ -0,0 +1,44 @@ +/* + * 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.ip.dump.params; + +public class AddressDumpParams { + + private final int interfaceIndex; + private final boolean isIpv6; + + public AddressDumpParams(final int interfaceIndex, final boolean isIpv6) { + this.interfaceIndex = interfaceIndex; + this.isIpv6 = isIpv6; + } + + public int getInterfaceIndex() { + return interfaceIndex; + } + + public boolean isIpv6() { + return isIpv6; + } + + @Override + public String toString() { + return "AddressDumpParams{" + + "interfaceIndex=" + interfaceIndex + + ", isIpv6=" + isIpv6 + + '}'; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java new file mode 100644 index 000000000..4d560a55b --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java @@ -0,0 +1,57 @@ +/* + * 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.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.hc2vpp.common.translate.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.rev161214.PbbRewriteStateInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.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 + init + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, + @Nonnull final PbbRewriteState readValue) { + ((PbbRewriteStateInterfaceAugmentationBuilder) parentBuilder).setPbbRewriteState(readValue); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/notification/InterfaceChangeNotificationProducer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/notification/InterfaceChangeNotificationProducer.java new file mode 100644 index 000000000..f7a159de7 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/notification/InterfaceChangeNotificationProducer.java @@ -0,0 +1,163 @@ +/* + * 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.notification; + +import com.google.common.base.Optional; +import com.google.common.collect.Lists; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.notification.ManagedNotificationProducer; +import io.fd.honeycomb.notification.NotificationCollector; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import java.util.ArrayList; +import java.util.Collection; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.concurrent.NotThreadSafe; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceDeleted; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceDeletedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceNameOrIndex; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStateChange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStateChangeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStatus; +import org.opendaylight.yangtools.yang.binding.Notification; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsNotification; +import io.fd.vpp.jvpp.core.dto.WantInterfaceEvents; +import io.fd.vpp.jvpp.core.dto.WantInterfaceEventsReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Notification producer for interface events. It starts interface notification stream and for every + * received notification, it transforms it into its BA equivalent and pushes into HC's notification collector. + */ +@NotThreadSafe +public final class InterfaceChangeNotificationProducer implements ManagedNotificationProducer, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(InterfaceChangeNotificationProducer.class); + + private final FutureJVppCore jvpp; + private final NamingContext interfaceContext; + private final MappingContext mappingContext; + @Nullable + private AutoCloseable notificationListenerReg; + + @Inject + public InterfaceChangeNotificationProducer(@Nonnull final FutureJVppCore jvpp, + @Named("interface-context") @Nonnull final NamingContext interfaceContext, + @Named("honeycomb-context") @Nonnull final MappingContext mappingContext) { + this.jvpp = jvpp; + this.interfaceContext = interfaceContext; + this.mappingContext = mappingContext; + } + + @Override + public void start(final NotificationCollector collector) { + LOG.trace("Starting interface notifications"); + enableDisableIfcNotifications(1); + LOG.debug("Interface notifications started successfully"); + notificationListenerReg = jvpp.getNotificationRegistry().registerSwInterfaceSetFlagsNotificationCallback( + swInterfaceSetFlagsNotification -> { + LOG.trace("Interface notification received: {}", swInterfaceSetFlagsNotification); + // TODO HONEYCOMB-166 this should be lazy + collector.onNotification(transformNotification(swInterfaceSetFlagsNotification)); + } + ); + } + + private Notification transformNotification(final SwInterfaceSetFlagsNotification swInterfaceSetFlagsNotification) { + if (swInterfaceSetFlagsNotification.deleted == 1) { + return new InterfaceDeletedBuilder().setName(getIfcName(swInterfaceSetFlagsNotification)).build(); + } else { + return new InterfaceStateChangeBuilder() + .setName(getIfcName(swInterfaceSetFlagsNotification)) + .setAdminStatus(swInterfaceSetFlagsNotification.adminUpDown == 1 + ? InterfaceStatus.Up + : InterfaceStatus.Down) + .setOperStatus(swInterfaceSetFlagsNotification.linkUpDown == 1 + ? InterfaceStatus.Up + : InterfaceStatus.Down) + .build(); + } + } + + /** + * Get mapped name for the interface. Best effort only! The mapping might not yet be stored in context + * data tree (write transaction is still in progress and context changes have not been committed yet, or + * VPP sends the notification before it returns create request(that would store mapping)). + *

+ * In case mapping is not available, index is used as name. + */ + private InterfaceNameOrIndex getIfcName(final SwInterfaceSetFlagsNotification swInterfaceSetFlagsNotification) { + final Optional optionalName = + interfaceContext.getNameIfPresent(swInterfaceSetFlagsNotification.swIfIndex, mappingContext); + return optionalName.isPresent() + ? new InterfaceNameOrIndex(optionalName.get()) + : new InterfaceNameOrIndex((long) swInterfaceSetFlagsNotification.swIfIndex); + } + + @Override + public void stop() { + LOG.trace("Stopping interface notifications"); + enableDisableIfcNotifications(0); + LOG.debug("Interface notifications stopped successfully"); + try { + if (notificationListenerReg != null) { + notificationListenerReg.close(); + } + } catch (Exception e) { + LOG.warn("Unable to properly close notification registration: {}", notificationListenerReg, e); + } + } + + private void enableDisableIfcNotifications(int enableDisable) { + final WantInterfaceEvents wantInterfaceEvents = new WantInterfaceEvents(); + wantInterfaceEvents.pid = 1; + wantInterfaceEvents.enableDisable = enableDisable; + final CompletionStage wantInterfaceEventsReplyCompletionStage; + try { + wantInterfaceEventsReplyCompletionStage = jvpp.wantInterfaceEvents(wantInterfaceEvents); + getReply(wantInterfaceEventsReplyCompletionStage.toCompletableFuture()); + } catch (VppBaseCallException | TimeoutException e) { + LOG.warn("Unable to {} interface notifications", enableDisable == 1 + ? "enable" + : "disable", e); + throw new IllegalStateException("Unable to control interface notifications", e); + } + } + + @Nonnull + @Override + public Collection> getNotificationTypes() { + final ArrayList> classes = Lists.newArrayList(); + classes.add(InterfaceStateChange.class); + classes.add(InterfaceDeleted.class); + return classes; + } + + @Override + public void close() throws Exception { + LOG.trace("Closing interface notifications producer"); + stop(); + } +} 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 new file mode 100644 index 000000000..cb4e11af5 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/util/SubInterfaceUtils.java @@ -0,0 +1,52 @@ +/* + * 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.util; + +import java.util.List; +import javax.annotation.Nonnegative; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; + +public final class SubInterfaceUtils { + + private SubInterfaceUtils() { + throw new UnsupportedOperationException("Utility class cannot be instantiated."); + } + + public static String getSubInterfaceName(final String superIfName, final int subIfaceId) { + return String.format("%s.%d", superIfName, subIfaceId); + } + + /** + * Returns number of sub-interface tags. + * + * @param tags data object that represents sub-interface tags + * @return number of sub interface tags + */ + @Nonnegative + public static int getNumberOfTags(@Nullable final Tags tags) { + if (tags == null) { + return 0; + } + final List tagList = tags.getTag(); + if (tagList == null) { + return 0; + } + return tagList.size(); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizer.java new file mode 100644 index 000000000..e7c1dea3d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizer.java @@ -0,0 +1,118 @@ +/* + * 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.vpp; + +import com.google.common.base.Preconditions; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +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.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.BdIpMacAddDel; +import io.fd.vpp.jvpp.core.dto.BdIpMacAddDelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer Customizer responsible for ARP termination table management.
Sends {@code bd_ip_mac_add_del} message to + * VPP.
Equivalent of invoking {@code vppctl set bridge-domain arp term} command. + */ +public class ArpTerminationTableEntryCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, ByteDataTranslator, + AddressTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ArpTerminationTableEntryCustomizer.class); + + private final NamingContext bdContext; + + public ArpTerminationTableEntryCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final NamingContext bdContext) { + super(futureJvpp); + this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ArpTerminationTableEntry dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Creating ARP termination table entry: {} {}", id, dataAfter); + bdIpMacAddDel(id, dataAfter, writeContext, true); + LOG.debug("L2 ARP termination table entry created successfully: {} {}", id, dataAfter); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ArpTerminationTableEntry dataBefore, + @Nonnull final ArpTerminationTableEntry dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException( + "ARP termination table entry update is not supported. It has to be deleted and then created."); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ArpTerminationTableEntry dataBefore, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Deleting ARP termination table entry entry: {} {}", id, dataBefore); + bdIpMacAddDel(id, dataBefore, writeContext, false); + LOG.debug("ARP termination table entry deleted successfully: {} {}", id, dataBefore); + } + + private void bdIpMacAddDel(@Nonnull final InstanceIdentifier id, + @Nonnull final ArpTerminationTableEntry entry, + final WriteContext writeContext, boolean isAdd) throws WriteFailedException { + final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); + final int bdId = bdContext.getIndex(bdName, writeContext.getMappingContext()); + + final BdIpMacAddDel request = createRequest(entry, bdId, isAdd); + LOG.debug("Sending l2FibAddDel request: {}", request); + final CompletionStage replyCompletionStage = + getFutureJVpp().bdIpMacAddDel(request); + + getReplyForWrite(replyCompletionStage.toCompletableFuture(), id); + } + + private BdIpMacAddDel createRequest(final ArpTerminationTableEntry entry, final int bdId, boolean isAdd) { + final BdIpMacAddDel request = new BdIpMacAddDel(); + request.bdId = bdId; + request.isAdd = booleanToByte(isAdd); + request.macAddress = parseMac(entry.getPhysAddress().getValue()); + + final IpAddress ipAddress = entry.getIpAddress(); + if (ipAddress.getIpv6Address() != null) { + // FIXME: HONEYCOMB-187 vpp does not support ipv6 in arp-termination table (based on analysis of l2_bd.c) + throw new UnsupportedOperationException("IPv6 address for ARP termination table is not supported yet"); + } + + request.ipAddress = ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(ipAddress.getIpv4Address())); + return request; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java new file mode 100644 index 000000000..b4b86264b --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java @@ -0,0 +1,137 @@ +/* + * 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.vpp; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Preconditions; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +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.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDel; +import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BridgeDomainCustomizer + extends FutureJVppCustomizer + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); + + private static final byte ADD_OR_UPDATE_BD = (byte) 1; + private final NamingContext bdContext; + @GuardedBy("this") + private int bridgeDomainIndexCounter = 1; + + public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext bdContext) { + super(futureJVppCore); + this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); + } + + private BridgeDomainAddDelReply addOrUpdateBridgeDomain(@Nonnull final InstanceIdentifier id, + final int bdId, @Nonnull final BridgeDomain bd) + throws WriteFailedException { + final BridgeDomainAddDelReply reply; + final BridgeDomainAddDel request = new BridgeDomainAddDel(); + request.bdId = bdId; + request.flood = booleanToByte(bd.isFlood()); + request.forward = booleanToByte(bd.isForward()); + request.learn = booleanToByte(bd.isLearn()); + request.uuFlood = booleanToByte(bd.isUnknownUnicastFlood()); + request.arpTerm = booleanToByte(bd.isArpTermination()); + request.isAdd = ADD_OR_UPDATE_BD; + + reply = getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); + LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId); + return reply; + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain dataBefore, + @Nonnull final WriteContext ctx) + throws WriteFailedException { + LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx); + final String bdName = dataBefore.getName(); + + // Invoke 1. check index, 2. increase index 3. create ND 4. store mapping in a synchronized block to prevent + // race conditions in case of concurrent invocation + synchronized (this) { + int index; + if (bdContext.containsIndex(bdName, ctx.getMappingContext())) { + index = bdContext.getIndex(bdName, ctx.getMappingContext()); + } else { + // Critical section due to bridgeDomainIndexCounter read and write access + // TODO HONEYCOMB-199 move this "get next available index" into naming context or an adapter + // or a dedicated object + + // Use counter to assign bridge domain index, but still check naming context if it's not taken there + while (bdContext.containsName(bridgeDomainIndexCounter, ctx.getMappingContext())) { + bridgeDomainIndexCounter++; + } + index = bridgeDomainIndexCounter; + } + addOrUpdateBridgeDomain(id, index, dataBefore); + bdContext.addName(index, bdName, ctx.getMappingContext()); + } + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain dataBefore, + @Nonnull final WriteContext ctx) + throws WriteFailedException { + LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx); + final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); + int bdId = bdContext.getIndex(bdName, ctx.getMappingContext()); + + final BridgeDomainAddDel request = new BridgeDomainAddDel(); + request.bdId = bdId; + + getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); + LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter, + @Nonnull final WriteContext ctx) + throws WriteFailedException { + LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter, + ctx); + + final String bdName = checkNotNull(dataAfter.getName()); + checkArgument(bdName.equals(dataBefore.getName()), + "BridgeDomain name changed. It should be deleted and then created."); + + addOrUpdateBridgeDomain(id, bdContext.getIndex(bdName, ctx.getMappingContext()), dataAfter); + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java new file mode 100644 index 000000000..6328555a3 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java @@ -0,0 +1,129 @@ +/* + * 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.vpp; + +import com.google.common.base.Preconditions; +import com.google.common.primitives.Longs; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.L2FibAddDel; +import io.fd.vpp.jvpp.core.dto.L2FibAddDelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer Customizer responsible for L2 FIB create/delete operations.
Sends {@code l2_fib_add_del} message to + * VPP.
Equivalent of invoking {@code vppctl l2fib add/del} command. + */ +public class L2FibEntryCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, ByteDataTranslator, MacTranslator, + JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); + + private final NamingContext bdContext; + private final NamingContext interfaceContext; + + public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); + this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntry dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Creating L2 FIB entry: {} {}", id, dataAfter); + l2FibAddDel(id, dataAfter, writeContext, true); + LOG.debug("L2 FIB entry created successfully: {} {}", id, dataAfter); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntry dataBefore, @Nonnull final L2FibEntry dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException( + "L2 FIB entry update is not supported. It has to be deleted and then created."); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntry dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Deleting L2 FIB entry: {} {}", id, dataBefore); + l2FibAddDel(id, dataBefore, writeContext, false); + LOG.debug("L2 FIB entry deleted successfully: {} {}", id, dataBefore); + } + + private void l2FibAddDel(@Nonnull final InstanceIdentifier id, @Nonnull final L2FibEntry entry, + final WriteContext writeContext, boolean isAdd) throws WriteFailedException { + final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); + final int bdId = bdContext.getIndex(bdName, writeContext.getMappingContext()); + + int swIfIndex = -1; + final String swIfName = entry.getOutgoingInterface(); + if (swIfName != null) { + swIfIndex = interfaceContext.getIndex(swIfName, writeContext.getMappingContext()); + } + + final L2FibAddDel l2FibRequest = createL2FibRequest(entry, bdId, swIfIndex, isAdd); + LOG.debug("Sending l2FibAddDel request: {}", l2FibRequest); + final CompletionStage l2FibAddDelReplyCompletionStage = + getFutureJVpp().l2FibAddDel(l2FibRequest); + + getReplyForWrite(l2FibAddDelReplyCompletionStage.toCompletableFuture(), id); + } + + private L2FibAddDel createL2FibRequest(final L2FibEntry entry, final int bdId, final int swIfIndex, boolean isAdd) { + final L2FibAddDel request = new L2FibAddDel(); + request.mac = macToLong(entry.getPhysAddress().getValue()); + request.bdId = bdId; + request.swIfIndex = swIfIndex; + request.isAdd = booleanToByte(isAdd); + if (isAdd) { + request.staticMac = booleanToByte(entry.isStaticConfig()); + request.filterMac = booleanToByte(L2FibFilter.class == entry.getAction()); + } + return request; + } + + // mac address is string of the form: 11:22:33:44:55:66 + // but VPP expects long value in the format 11:22:33:44:55:66:XX:XX + private long macToLong(final String macAddress) { + final byte[] mac = parseMac(macAddress); + return Longs.fromBytes(mac[0], mac[1], mac[2], mac[3], + mac[4], mac[5], (byte) 0, (byte) 0); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReader.java new file mode 100644 index 000000000..daaa88c56 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReader.java @@ -0,0 +1,207 @@ +/* + * 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.vppclassifier; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import com.google.common.primitives.UnsignedInts; +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.ListReaderCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDetails; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.xml.bind.DatatypeConverter; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; +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; + +/** + * Reader customizer responsible for classify session read.
to VPP.
Equivalent to invoking {@code vppctl show + * class table verbose} command. + */ +public class ClassifySessionReader extends FutureJVppCustomizer + implements ListReaderCustomizer, + InterfaceDataTranslator, VppNodeReader, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionReader.class); + static final String CACHE_KEY = ClassifySessionReader.class.getName(); + + private final VppClassifierContextManager classifyTableContext; + + public ClassifySessionReader(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(futureJVppCore); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void merge(@Nonnull final Builder builder, + @Nonnull final List readData) { + ((ClassifyTableBuilder) builder).setClassifySession(readData); + } + + @Nonnull + @Override + public ClassifySessionBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new ClassifySessionBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySessionBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes for classify session: {}", id); + + final ClassifySessionKey key = id.firstKeyOf(ClassifySession.class); + checkArgument(key != null, "could not find ClassifySession key in {}", id); + + final ClassifySessionDetailsReplyDump classifySessionDump = dumpClassifySessions(id, ctx); + final byte[] match = DatatypeConverter.parseHexBinary(key.getMatch().getValue().replace(":", "")); + final Optional classifySession = + findClassifySessionDetailsByMatch(classifySessionDump, match); + + if (classifySession.isPresent()) { + final ClassifySessionDetails detail = classifySession.get(); + builder.setHitNext( + readVppNode(detail.tableId, detail.hitNextIndex, classifyTableContext, ctx.getMappingContext(), LOG) + .get()); + if (detail.opaqueIndex != ~0) { + // value is specified: + builder.setOpaqueIndex(readOpaqueIndex(detail.tableId, detail.opaqueIndex, ctx.getMappingContext())); + } + builder.setAdvance(detail.advance); + builder.setMatch(key.getMatch()); + + if (LOG.isTraceEnabled()) { + LOG.trace("Attributes for classify session {} successfully read: {}", id, builder.build()); + } + } + } + + private OpaqueIndex readOpaqueIndex(final int tableIndex, final int opaqueIndex, final MappingContext ctx) { + // We first try to map the value to a vpp node, if that fails, simply wrap the u32 value + // TODO: HONEYCOMB-118 the approach might fail if the opaqueIndex contains small value that collides + // with some of the adjacent nodes + + final Optional node = readVppNode(tableIndex, opaqueIndex, classifyTableContext, ctx, LOG); + if (node.isPresent()) { + return new OpaqueIndex(node.get()); + } else { + return new OpaqueIndex(UnsignedInts.toLong(opaqueIndex)); + } + } + + @Nullable + private ClassifySessionDetailsReplyDump dumpClassifySessions(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext ctx) + throws ReadFailedException { + final ClassifyTableKey tableKey = id.firstKeyOf(ClassifyTable.class); + checkArgument(tableKey != null, "could not find ClassifyTable key in {}", id); + + final String cacheKey = CACHE_KEY + tableKey; + + ClassifySessionDetailsReplyDump classifySessionDump = + (ClassifySessionDetailsReplyDump) ctx.getModificationCache().get(cacheKey); + if (classifySessionDump != null) { + LOG.debug("Classify sessions is present in cache: {}", cacheKey); + return classifySessionDump; + } + + final String tableName = tableKey.getName(); + checkState(classifyTableContext.containsTable(tableName, ctx.getMappingContext()), + "Reading classify sessions for table {}, but table index could not be found in the classify table context", + tableName); + final int tableId = classifyTableContext.getTableIndex(tableName, ctx.getMappingContext()); + LOG.debug("Dumping classify sessions for classify table id={}", tableId); + + + final ClassifySessionDump dumpRequest = new ClassifySessionDump(); + dumpRequest.tableId = tableId; + final int timeOut = 30; // there can be many session with current ietf-acl implementation (could be probably + // removed after fixing HONEYCOMB-247) + classifySessionDump = + getReplyForRead(getFutureJVpp().classifySessionDump(dumpRequest).toCompletableFuture(), id, timeOut); + + if (classifySessionDump != null) { + // update the cache: + ctx.getModificationCache().put(cacheKey, classifySessionDump); + } + + return classifySessionDump; + } + + private static Optional findClassifySessionDetailsByMatch( + @Nullable final ClassifySessionDetailsReplyDump classifySessionDump, @Nonnull final byte[] match) { + if (classifySessionDump != null && classifySessionDump.classifySessionDetails != null) { + final List details = classifySessionDump.classifySessionDetails; + final List filteredSessions = details.stream() + .filter(singleDetail -> Arrays.equals(singleDetail.match, match)).collect(Collectors.toList()); + if (filteredSessions.isEmpty()) { + return Optional.absent(); + } else if (filteredSessions.size() == 1) { + return Optional.of(filteredSessions.get(0)); + } else { + throw new IllegalStateException(String.format( + "Found %d classify sessions witch given match. Single session expected.", + filteredSessions.size())); + } + } + return Optional.absent(); + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading list of keys for classify sessions: {}", id); + + final ClassifySessionDetailsReplyDump classifySessionDump = dumpClassifySessions(id, ctx); + if (classifySessionDump != null && classifySessionDump.classifySessionDetails != null) { + return classifySessionDump.classifySessionDetails.stream() + .map(detail -> new ClassifySessionKey(new HexString(printHexBinary(detail.match)))) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriter.java new file mode 100644 index 000000000..4e1a51265 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriter.java @@ -0,0 +1,165 @@ +/* + * 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.vppclassifier; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.xml.bind.DatatypeConverter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer customizer responsible for classify session create/delete.
Sends {@code classify_add_del_session} message + * to VPP.
Equivalent to invoking {@code vppctl classify table} command. + */ +public class ClassifySessionWriter extends VppNodeWriter + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionWriter.class); + private final VppClassifierContextManager classifyTableContext; + + public ClassifySessionWriter(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(futureJVppCore); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySession dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Creating classify session: iid={} dataAfter={}", id, dataAfter); + try { + classifyAddDelSession(true, id, dataAfter, writeContext); + LOG.debug("Successfully created classify session: iid={} dataAfter={}", id, dataAfter); + } catch (VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySession dataBefore, + @Nonnull final ClassifySession dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Classify session update is not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySession dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Removing classify session: iid={} dataBefore={}", id, dataBefore); + try { + classifyAddDelSession(false, id, dataBefore, writeContext); + LOG.debug("Successfully removed classify session: iid={} dataBefore={}", id, dataBefore); + } catch (VppBaseCallException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + } + + private void classifyAddDelSession(final boolean isAdd, @Nonnull final InstanceIdentifier id, + @Nonnull final ClassifySession classifySession, + @Nonnull final WriteContext writeContext) + throws VppBaseCallException, WriteFailedException { + final ClassifyTableKey tableKey = id.firstKeyOf(ClassifyTable.class); + checkArgument(tableKey != null, "could not find classify table key in {}", id); + + final String tableName = tableKey.getName(); + checkState(classifyTableContext.containsTable(tableName, writeContext.getMappingContext()), + "Could not find classify table index for {} in the classify table context", tableName); + final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); + + final ClassifyTable classifyTable = + getClassifyTable(writeContext, id.firstIdentifierOf(ClassifyTable.class), isAdd); + final int hitNextIndex = getNodeIndex(classifySession.getHitNext(), classifyTable, classifyTableContext, + writeContext.getMappingContext(), id); + final int opaqueIndex = + getOpaqueIndex(classifySession.getOpaqueIndex(), classifyTable, writeContext.getMappingContext(), id); + + final CompletionStage createClassifyTableReplyCompletionStage = getFutureJVpp() + .classifyAddDelSession( + getClassifyAddDelSessionRequest(isAdd, classifySession, tableIndex, hitNextIndex, opaqueIndex)); + + getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); + } + + private ClassifyTable getClassifyTable(final WriteContext writeContext, + @Nonnull final InstanceIdentifier id, + final boolean isAdd) { + final Optional classifyTable; + if (isAdd) { + classifyTable = writeContext.readAfter(id); + } else { + classifyTable = writeContext.readBefore(id); + } + return classifyTable.get(); + } + + private ClassifyAddDelSession getClassifyAddDelSessionRequest(final boolean isAdd, + @Nonnull final ClassifySession classifySession, + final int tableIndex, + final int hitNextIndex, + final int opaqueIndex) { + ClassifyAddDelSession request = new ClassifyAddDelSession(); + request.isAdd = booleanToByte(isAdd); + request.tableIndex = tableIndex; + request.hitNextIndex = hitNextIndex; + request.opaqueIndex = opaqueIndex; + + // default 0: + request.advance = classifySession.getAdvance(); + + request.match = DatatypeConverter.parseHexBinary(classifySession.getMatch().getValue().replace(":", "")); + return request; + } + + private int getOpaqueIndex(@Nullable final OpaqueIndex opaqueIndex, final ClassifyTable classifyTable, + final MappingContext ctx, final InstanceIdentifier id) + throws VppBaseCallException, WriteFailedException { + if (opaqueIndex == null) { + return ~0; // value not specified + } + if (opaqueIndex.getUint32() != null) { + return opaqueIndex.getUint32().intValue(); + } else { + return getNodeIndex(opaqueIndex.getVppNode(), classifyTable, classifyTableContext, ctx, id); + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReader.java new file mode 100644 index 000000000..fba5fb694 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReader.java @@ -0,0 +1,171 @@ +/* + * 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.vppclassifier; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import com.google.common.primitives.UnsignedInts; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.vpp.jvpp.core.dto.ClassifyTableIds; +import io.fd.vpp.jvpp.core.dto.ClassifyTableIdsReply; +import io.fd.vpp.jvpp.core.dto.ClassifyTableInfo; +import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Arrays; +import java.util.Collections; +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.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; +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; + +/** + * Reader customizer responsible for classify table read.
to VPP.
Equivalent to invoking {@code vppctl show + * class table} command. + */ +public class ClassifyTableReader extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, VppNodeReader, + MacTranslator, InterfaceDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableReader.class); + private final VppClassifierContextManager classifyTableContext; + + public ClassifyTableReader(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(futureJVppCore); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + + @Override + public void merge(@Nonnull final Builder builder, + @Nonnull final List readData) { + ((VppClassifierStateBuilder) builder).setClassifyTable(readData); + } + + @Nonnull + @Override + public ClassifyTableBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new ClassifyTableBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTableBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes for classify table: {}", id); + + final ClassifyTableKey key = id.firstKeyOf(ClassifyTable.class); + checkArgument(key != null, "could not find ClassifyTable key in {}", id); + final ClassifyTableInfo request = new ClassifyTableInfo(); + + final String tableName = key.getName(); + if (!classifyTableContext.containsTable(tableName, ctx.getMappingContext())) { + LOG.debug("Could not find classify table {} in the naming context", tableName); + return; + } + request.tableId = classifyTableContext.getTableIndex(tableName, ctx.getMappingContext()); + + + final ClassifyTableInfoReply reply = + getReplyForRead(getFutureJVpp().classifyTableInfo(request).toCompletableFuture(), id); + + // mandatory values: + builder.setName(tableName); + builder.setKey(key); + builder.setNbuckets(UnsignedInts.toLong(reply.nbuckets)); + builder.setSkipNVectors(UnsignedInts.toLong(reply.skipNVectors)); + + // optional value read from context + final Optional tableBaseNode = + classifyTableContext.getTableBaseNode(tableName, ctx.getMappingContext()); + if (tableBaseNode.isPresent()) { + builder.setClassifierNode(new VppNodeName(tableBaseNode.get())); + } + + builder.setMissNext( + readVppNode(reply.tableId, reply.missNextIndex, classifyTableContext, ctx.getMappingContext(), LOG) + .get()); + builder.setMask(new HexString(printHexBinary(reply.mask))); + builder.setActiveSessions(UnsignedInts.toLong(reply.activeSessions)); + + if (reply.nextTableIndex != ~0) { + // next table index is present: + builder.setNextTable(classifyTableContext.getTableName(reply.nextTableIndex, ctx.getMappingContext())); + } + + if (LOG.isTraceEnabled()) { + LOG.trace("Attributes for classify table {} successfully read: {}", id, builder.build()); + } + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext context) throws ReadFailedException { + LOG.debug("Reading list of keys for classify tables: {}", id); + + final ClassifyTableIdsReply classifyTableIdsReply = + getReplyForRead(getFutureJVpp().classifyTableIds(new ClassifyTableIds()).toCompletableFuture(), + id); + if (classifyTableIdsReply.ids != null) { + return Arrays.stream(classifyTableIdsReply.ids).mapToObj(i -> { + final String tableName = classifyTableContext.getTableName(i, context.getMappingContext()); + LOG.trace("Classify table with name: {} and index: {} found in VPP", tableName, i); + return new ClassifyTableKey(tableName); + }).collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, @Nonnull final ClassifyTable readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableBuilder(readValue) + .setName(readValue.getName()) + .build()); + } + + static InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InstanceIdentifier.create(VppClassifier.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey(id.firstKeyOf(ClassifyTable.class).getName())); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriter.java new file mode 100644 index 000000000..62b6a2142 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriter.java @@ -0,0 +1,149 @@ +/* + * 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.vppclassifier; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import javax.xml.bind.DatatypeConverter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer customizer responsible for classify table create/delete.
Sends {@code classify_add_del_table} message to + * VPP.
Equivalent to invoking {@code vppctl classify table} command. + */ +public class ClassifyTableWriter extends VppNodeWriter + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableWriter.class); + private final VppClassifierContextManager classifyTableContext; + + public ClassifyTableWriter(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final VppClassifierContextManager classifyTableContext) { + super(futureJVppCore); + this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTable dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Creating classify table: iid={} dataAfter={}", id, dataAfter); + try { + final int newTableIndex = + classifyAddDelTable(true, id, dataAfter, ~0 /* value not present */, + writeContext.getMappingContext()); + + // Add classify table name <-> vpp index mapping to the naming context: + classifyTableContext.addTable(newTableIndex, dataAfter.getName(), dataAfter.getClassifierNode(), + writeContext.getMappingContext()); + LOG.debug("Successfully created classify table(id={]): iid={} dataAfter={}", newTableIndex, id, dataAfter); + } catch (VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTable dataBefore, @Nonnull final ClassifyTable dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Classify table update is not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTable dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Removing classify table: iid={} dataBefore={}", id, dataBefore); + final String tableName = dataBefore.getName(); + checkState(classifyTableContext.containsTable(tableName, writeContext.getMappingContext()), + "Removing classify table {}, but index could not be found in the classify table context", tableName); + + final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); + try { + classifyAddDelTable(false, id, dataBefore, tableIndex, writeContext.getMappingContext()); + + // Remove deleted interface from interface context: + classifyTableContext.removeTable(dataBefore.getName(), writeContext.getMappingContext()); + LOG.debug("Successfully removed classify table(id={]): iid={} dataAfter={}", tableIndex, id, dataBefore); + } catch (VppBaseCallException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + } + + private int classifyAddDelTable(final boolean isAdd, @Nonnull final InstanceIdentifier id, + @Nonnull final ClassifyTable table, final int tableId, final MappingContext ctx) + throws VppBaseCallException, WriteFailedException { + + final int missNextIndex = + getNodeIndex(table.getMissNext(), table, classifyTableContext, ctx, id); + + final CompletionStage createClassifyTableReplyCompletionStage = + getFutureJVpp() + .classifyAddDelTable(getClassifyAddDelTableRequest(isAdd, tableId, table, missNextIndex, ctx)); + + final ClassifyAddDelTableReply reply = + getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); + return reply.newTableIndex; + } + + private ClassifyAddDelTable getClassifyAddDelTableRequest(final boolean isAdd, final int tableIndex, + @Nonnull final ClassifyTable table, + final int missNextIndex, + @Nonnull final MappingContext ctx) { + final ClassifyAddDelTable request = new ClassifyAddDelTable(); + request.isAdd = booleanToByte(isAdd); + request.tableIndex = tableIndex; + + // mandatory, all u32 values are permitted: + request.nbuckets = table.getNbuckets().intValue(); + request.memorySize = table.getMemorySize().intValue(); + request.skipNVectors = table.getSkipNVectors().intValue(); + + // mandatory + request.missNextIndex = missNextIndex; + + final String nextTable = table.getNextTable(); + if (isAdd && nextTable != null) { + request.nextTableIndex = classifyTableContext.getTableIndex(nextTable, ctx); + } else { + request.nextTableIndex = ~0; // value not specified + } + request.mask = DatatypeConverter.parseHexBinary(table.getMask().getValue().replace(":", "")); + checkArgument(request.mask.length % 16 == 0, "Number of mask bytes must be multiple of 16."); + request.matchNVectors = request.mask.length / 16; + + return request; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManager.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManager.java new file mode 100644 index 000000000..c06ef2700 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManager.java @@ -0,0 +1,106 @@ +/* + * 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.vppclassifier; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; + +/** + * Manages metadata for vpp-classifier + */ +public interface VppClassifierContextManager { + + /** + * Creates metadata for classify table. + * + * @param id classify table index + * @param name classify table name + * @param classifierNode name of VPP node the table is defined for + * @param ctx mapping context providing context data for current transaction + */ + void addTable(final int id, @Nonnull final String name, @Nullable final VppNodeName classifierNode, + @Nonnull final MappingContext ctx); + + /** + * Check whether metadata for given classify table metadata is present. + * + * @param name classify table name + * @param ctx mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + boolean containsTable(@Nonnull String name, @Nonnull final MappingContext ctx); + + /** + * Returns classify table index associated with the given name. + * + * @param name classify table name + * @param ctx mapping context providing context data for current transaction + * @return integer index value matching supplied classify table name + * @throws IllegalArgumentException if classify table was not found + */ + int getTableIndex(@Nonnull final String name, @Nonnull final MappingContext ctx); + + /** + * Retrieves classify table name for given id. If not present, artificial name will be generated. + * + * @param id classify table index + * @param ctx mapping context providing context data for current transaction + * @return classify table name matching supplied index + */ + String getTableName(final int id, @Nonnull final MappingContext ctx); + + /** + * Returns name of the base vpp node associated with the classify table. + * + * @param name classify table name + * @param ctx mapping context providing context data for current transaction + * @return name of VPP node the table is defined for + */ + Optional getTableBaseNode(final String name, @Nonnull final MappingContext ctx); + + /** + * Removes classify table metadata from current context. + * + * @param name classify table name + * @param ctx mapping context providing context data for current transaction + */ + void removeTable(@Nonnull final String name, @Nonnull final MappingContext ctx); + + /** + * Adds relative node index to node name mapping for given classify table. + * + * @param tableName classify table name + * @param nodeIndex index of a vpp node, relative to table's base node + * @param nodeName name of a vpp node + * @param ctx mapping context providing context data for current transaction + */ + void addNodeName(@Nonnull String tableName, final int nodeIndex, @Nonnull final String nodeName, + @Nonnull final MappingContext ctx); + + /** + * Retrieves node name associated with the given classify table and node index. + * + * @param tableIndex classify table index + * @param nodeIndex relative index of a vpp node + * @param ctx mapping context providing context data for current transaction + * @return name of vpp node + */ + Optional getNodeName(final int tableIndex, final int nodeIndex, @Nonnull final MappingContext ctx); +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImpl.java new file mode 100644 index 000000000..2255c78a7 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImpl.java @@ -0,0 +1,181 @@ +/* + * 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.vppclassifier; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.inject.Inject; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.util.read.BindingBrokerReader; +import java.util.List; +import java.util.stream.Collector; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.inject.Named; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +/** + * Facade on top of {@link MappingContext} that manages {@link ClassifyTableContext}. + */ +public final class VppClassifierContextManagerImpl implements VppClassifierContextManager { + private static final Collector SINGLE_ITEM_COLLECTOR = + RWUtils.singleItemCollector(); + + @VisibleForTesting + static final InstanceIdentifier + VPP_CLASSIFIER_CONTEXT_IID = KeyedInstanceIdentifier.create(VppClassifierContext.class); + private final String artificialNamePrefix; + + /** + * Creates new VppClassifierContextManagerImpl. + * + * @param artificialNamePrefix artificial name to be used to generate names for classify tables without existing + * metadata + */ + public VppClassifierContextManagerImpl(@Nonnull final String artificialNamePrefix) { + this.artificialNamePrefix = + Preconditions.checkNotNull(artificialNamePrefix, "artificialNamePrefix should not be null"); + } + + private KeyedInstanceIdentifier getMappingIid(final String name) { + return VPP_CLASSIFIER_CONTEXT_IID.child(ClassifyTableContext.class, new ClassifyTableContextKey(name)); + } + + @Override + public void addTable(final int id, @Nonnull final String name, @Nullable final VppNodeName classifierNode, + @Nonnull final MappingContext ctx) { + final KeyedInstanceIdentifier mappingIid = getMappingIid(name); + final ClassifyTableContextBuilder tableCtx = new ClassifyTableContextBuilder().setIndex(id).setName(name); + if (classifierNode != null) { + tableCtx.setClassifierNodeName(classifierNode.getValue()); + } + ctx.put(mappingIid, tableCtx.build()); + } + + @Override + public boolean containsTable(@Nonnull final String name, @Nonnull final MappingContext ctx) { + final Optional read = ctx.read(getMappingIid(name)); + return read.isPresent(); + } + + @Override + public int getTableIndex(@Nonnull final String name, @Nonnull final MappingContext ctx) { + final Optional read = ctx.read(getMappingIid(name)); + checkArgument(read.isPresent(), "No mapping stored for name: %s", name); + return read.get().getIndex(); + } + + @Override + public String getTableName(final int id, @Nonnull final MappingContext ctx) { + if (!containsName(id, ctx)) { + final String artificialName = getArtificialName(id); + addTable(id, artificialName, null, ctx); + } + + final Optional read = ctx.read(VPP_CLASSIFIER_CONTEXT_IID); + checkState(read.isPresent(), "VppClassifierContext for index: %s is not present. But should be", id); + + return read.get().getClassifyTableContext().stream() + .filter(t -> t.getIndex().equals(id)) + .collect(SINGLE_ITEM_COLLECTOR).getName(); + } + + private boolean containsName(final int index, @Nonnull final MappingContext mappingContext) { + final Optional read = mappingContext.read(VPP_CLASSIFIER_CONTEXT_IID); + return read.isPresent() + ? read.get().getClassifyTableContext().stream().anyMatch(t -> t.getIndex().equals(index)) + : false; + } + + @Override + public Optional getTableBaseNode(@Nonnull final String name, @Nonnull final MappingContext ctx) { + final Optional read = ctx.read(getMappingIid(name)); + if (read.isPresent()) { + return Optional.fromNullable(read.get().getClassifierNodeName()); + } + return Optional.absent(); + } + + @Override + public void removeTable(@Nonnull final String name, @Nonnull final MappingContext ctx) { + ctx.delete(getMappingIid(name)); + } + + @Override + public void addNodeName(@Nonnull final String tableName, final int nodeIndex, + @Nonnull final String nodeName, + @Nonnull final MappingContext ctx) { + final KeyedInstanceIdentifier iid = + getMappingIid(tableName).child(NodeContext.class, new NodeContextKey(nodeName)); + ctx.put(iid, new NodeContextBuilder().setName(nodeName).setIndex(nodeIndex).build()); + } + + @Override + public Optional getNodeName(final int tableIndex, final int nodeIndex, @Nonnull final MappingContext ctx) { + if (!containsName(tableIndex, ctx)) { + return Optional.absent(); + } + final String tableName = getTableName(tableIndex, ctx); + final Optional tableCtx = ctx.read(getMappingIid(tableName)); + final List nodeContext = tableCtx.get().getNodeContext(); + if (nodeContext == null) { + return Optional.absent(); + } + return Optional.fromNullable(nodeContext.stream() + .filter(n -> n.getIndex().equals(nodeIndex)) + .findFirst() + .map(nodes -> nodes.getName()) + .orElse(null)); + } + + private String getArtificialName(final int index) { + return artificialNamePrefix + index; + } + + public static final class ContextsReaderFactory implements ReaderFactory { + + @Inject + @Named("honeycomb-context") + private DataBroker contextBindingBrokerDependency; + + @Override + public void init(final ModifiableReaderRegistryBuilder registry) { + registry.add(new BindingBrokerReader<>(VPP_CLASSIFIER_CONTEXT_IID, + contextBindingBrokerDependency, + LogicalDatastoreType.OPERATIONAL, VppClassifierContextBuilder.class)); + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeReader.java new file mode 100644 index 000000000..c25a4572c --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeReader.java @@ -0,0 +1,45 @@ +/* + * 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.vppclassifier; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.slf4j.Logger; + +interface VppNodeReader { + + /** + * Converts vpp node index to YANG representation of vpp node. + * + * @param nodeIndex index of vpp node treated as signed integer. + * @return vpp node representation + */ + default Optional readVppNode(final int tableIndex, final int nodeIndex, + @Nonnull final VppClassifierContextManager vppClassifierContextManager, + @Nonnull final MappingContext ctx, @Nonnull final Logger log) { + final PacketHandlingAction action = PacketHandlingAction.forValue(nodeIndex); + if (action == null) { + return vppClassifierContextManager.getNodeName(tableIndex, nodeIndex, ctx) + .transform(nodeName -> new VppNode(new VppNodeName(nodeName))); + } + return Optional.of(new VppNode(action)); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeWriter.java new file mode 100644 index 000000000..dd0b2d5ec --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppclassifier/VppNodeWriter.java @@ -0,0 +1,79 @@ +/* + * 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.vppclassifier; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.GetNextIndex; +import io.fd.vpp.jvpp.core.dto.GetNextIndexReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +abstract class VppNodeWriter extends FutureJVppCustomizer implements JvppReplyConsumer { + + protected VppNodeWriter(@Nonnull final FutureJVppCore futureJvpp) { + super(futureJvpp); + } + + protected int getNodeIndex(@Nonnull final VppNode node, @Nonnull final ClassifyTable classifyTable, + @Nonnull final VppClassifierContextManager vppClassifierContextManager, + @Nonnull final MappingContext ctx, @Nonnull final InstanceIdentifier id) + throws VppBaseCallException, WriteFailedException { + if (node.getPacketHandlingAction() != null) { + return node.getPacketHandlingAction().getIntValue(); + } else { + return nodeNameToIndex(classifyTable, node.getVppNodeName().getValue(), vppClassifierContextManager, ctx, + id); + } + } + + private int nodeNameToIndex(@Nonnull final ClassifyTable classifyTable, @Nonnull final String nextNodeName, + @Nonnull final VppClassifierContextManager vppClassifierContextManager, + @Nonnull final MappingContext ctx, @Nonnull final InstanceIdentifier id) + throws WriteFailedException { + checkArgument(classifyTable != null && classifyTable.getClassifierNode() != null, + "to use relative node names, table classifier node needs to be provided"); + final GetNextIndex request = new GetNextIndex(); + request.nodeName = classifyTable.getClassifierNode().getValue().getBytes(); + request.nextName = nextNodeName.getBytes(); + final CompletionStage getNextIndexCompletionStage = + getFutureJVpp().getNextIndex(request); + + final GetNextIndexReply reply; + try { + reply = getReplyForRead(getNextIndexCompletionStage.toCompletableFuture(), id); + + // vpp does not provide relative node index to node name conversion (https://jira.fd.io/browse/VPP-219) + // as a workaround we need to add mapping to vpp-classfier-context + vppClassifierContextManager.addNodeName(classifyTable.getName(), reply.nextIndex, nextNodeName, ctx); + } catch (ReadFailedException e) { + throw new WriteFailedException(id, String.format("Failed to get node index for %s relative to %s", + nextNodeName, classifyTable.getClassifierNode()), e); + } + return reply.nextIndex; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizer.java new file mode 100644 index 000000000..e6f3bbb49 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizer.java @@ -0,0 +1,181 @@ +/* + * 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.vppstate; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Vpp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; +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 BridgeDomainCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, ByteDataTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); + private final NamingContext bdContext; + + public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext bdContext) { + super(futureJVppCore); + this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomainBuilder builder, @Nonnull final ReadContext context) + throws ReadFailedException { + LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: id={}, builderbuilder={}, context={}", + id, builder, context); + + final BridgeDomainKey key = id.firstKeyOf(id.getTargetType()); + LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: key={}", key); + + final int bdId = bdContext.getIndex(key.getName(), context.getMappingContext()); + LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: bdId={}", bdId); + + BridgeDomainDetailsReplyDump reply; + BridgeDomainDetails bridgeDomainDetails; + final BridgeDomainDump request = new BridgeDomainDump(); + request.bdId = bdContext.getIndex(key.getName(), context.getMappingContext()); + try { + reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get(); + bridgeDomainDetails = Iterables.getOnlyElement(reply.bridgeDomainDetails); + } catch (Exception e) { + LOG.debug("Unable to read bridge domain: {}", key.getName(), e); + return; + } + + logBridgeDomainDetails(bridgeDomainDetails); + + builder.setName(key.getName()); + builder.setArpTermination(byteToBoolean(bridgeDomainDetails.arpTerm)); + builder.setFlood(byteToBoolean(bridgeDomainDetails.flood)); + builder.setForward(byteToBoolean(bridgeDomainDetails.forward)); + builder.setLearn(byteToBoolean(bridgeDomainDetails.learn)); + builder.setUnknownUnicastFlood(byteToBoolean(bridgeDomainDetails.uuFlood)); + } + + private void logBridgeDomainDetails(final BridgeDomainDetails bridgeDomainDetails) { + LOG.debug("bridgeDomainDetails={}", bridgeDomainDetails); + if (bridgeDomainDetails != null) { + LOG.debug("bridgeDomainDetails.arpTerm={}", bridgeDomainDetails.arpTerm); + LOG.debug("bridgeDomainDetails.bdId={}", bridgeDomainDetails.bdId); + LOG.debug("bridgeDomainDetails.bviSwIfIndex={}", bridgeDomainDetails.bviSwIfIndex); + LOG.debug("bridgeDomainDetails.flood={}", bridgeDomainDetails.flood); + LOG.debug("bridgeDomainDetails.forward={}", bridgeDomainDetails.forward); + LOG.debug("bridgeDomainDetails.learn={}", bridgeDomainDetails.learn); + LOG.debug("bridgeDomainDetails.nSwIfs={}", bridgeDomainDetails.nSwIfs); + LOG.debug("bridgeDomainDetails.uuFlood={}", bridgeDomainDetails.uuFlood); + } + } + + @Nonnull + @Override + public BridgeDomainBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new BridgeDomainBuilder(); + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext context) throws ReadFailedException { + final BridgeDomainDump request = new BridgeDomainDump(); + request.bdId = -1; // dump call + + BridgeDomainDetailsReplyDump reply; + try { + reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get(); + } catch (Exception e) { + throw new ReadFailedException(id, e); + } + + if (reply == null || reply.bridgeDomainDetails == null) { + return Collections.emptyList(); + } + + final int bIdsLength = reply.bridgeDomainDetails.size(); + LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bIds.length={}", bIdsLength); + if (bIdsLength == 0) { + // No bridge domains + return Collections.emptyList(); + } + + final List allIds = new ArrayList<>(bIdsLength); + for (BridgeDomainDetails detail : reply.bridgeDomainDetails) { + logBridgeDomainDetails(detail); + + final String bName = bdContext.getName(detail.bdId, context.getMappingContext()); + LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bName={}", bName); + allIds.add(new BridgeDomainKey(bName)); + } + + return allIds; + } + + @Override + public void merge(@Nonnull final Builder builder, + @Nonnull final List readData) { + ((BridgeDomainsBuilder) builder).setBridgeDomain(readData); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainBuilder() + .setName(readValue.getName()) + .setLearn(readValue.isLearn()) + .setUnknownUnicastFlood(readValue.isUnknownUnicastFlood()) + .setArpTermination(readValue.isArpTermination()) + .setFlood(readValue.isFlood()) + .setForward(readValue.isForward()) + .build()); + } + + static InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InstanceIdentifier.create(Vpp.class).child(BridgeDomains.class).child( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey( + id.firstKeyOf(BridgeDomain.class).getName())); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java new file mode 100644 index 000000000..2605293c5 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java @@ -0,0 +1,165 @@ +/* + * 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.vppstate; + +import com.google.common.base.Preconditions; +import com.google.common.primitives.Longs; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceDataTranslator; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.L2FibTableDump; +import io.fd.vpp.jvpp.core.dto.L2FibTableEntry; +import io.fd.vpp.jvpp.core.dto.L2FibTableEntryReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibForward; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; +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 L2FibEntryCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, ByteDataTranslator, + InterfaceDataTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); + + private static final Collector SINGLE_ITEM_COLLECTOR = + RWUtils.singleItemCollector(); + + private final NamingContext bdContext; + private final NamingContext interfaceContext; + + public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); + this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntryBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + + final L2FibEntryKey key = id.firstKeyOf(id.getTargetType()); + final BridgeDomainKey bridgeDomainKey = id.firstKeyOf(BridgeDomain.class); + final int bdId = bdContext.getIndex(bridgeDomainKey.getName(), ctx.getMappingContext()); + LOG.debug("Reading L2 FIB entry: key={}. bridgeDomainKey={}, bdId={}", key, bridgeDomainKey, bdId); + + try { + // TODO HONEYCOMB-186 use cached l2FibTable + final L2FibTableEntry entry = dumpL2Fibs(id, bdId).stream().filter(e -> key.getPhysAddress() + .equals(new PhysAddress(vppPhysAddrToYang(Longs.toByteArray(e.mac), 2)))) + .collect(SINGLE_ITEM_COLLECTOR); + + builder.setAction(byteToBoolean(entry.filterMac) + ? L2FibFilter.class + : L2FibForward.class); + builder.setBridgedVirtualInterface(byteToBoolean(entry.bviMac)); + + if (entry.swIfIndex != -1) { + builder.setOutgoingInterface(interfaceContext.getName(entry.swIfIndex, ctx.getMappingContext())); + } + builder.setStaticConfig(byteToBoolean(entry.staticMac)); + builder.setPhysAddress(key.getPhysAddress()); + builder.setKey(key); + } catch (Exception e) { + throw new ReadFailedException(id, e); + } + } + + @Nonnull + private List dumpL2Fibs(final InstanceIdentifier id, final int bdId) + throws ReadFailedException { + final L2FibTableDump l2FibRequest = new L2FibTableDump(); + l2FibRequest.bdId = bdId; + + final CompletableFuture l2FibTableDumpCompletableFuture = + getFutureJVpp().l2FibTableDump(l2FibRequest).toCompletableFuture(); + + final L2FibTableEntryReplyDump dump = getReplyForRead(l2FibTableDumpCompletableFuture, id); + + if (null == dump || null == dump.l2FibTableEntry) { + return Collections.emptyList(); + } else { + return dump.l2FibTableEntry; + } + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext ctx) throws ReadFailedException { + final BridgeDomainKey bridgeDomainKey = id.firstKeyOf(BridgeDomain.class); + final int bdId = bdContext.getIndex(bridgeDomainKey.getName(), ctx.getMappingContext()); + + LOG.debug("Reading L2 FIB for bridge domain {} (bdId={})", bridgeDomainKey, bdId); + return dumpL2Fibs(id, bdId).stream() + .map(entry -> new L2FibEntryKey( + new PhysAddress(vppPhysAddrToYang(Longs.toByteArray(entry.mac), 2)))) + .collect(Collectors.toList()); + } + + @Override + public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { + ((L2FibTableBuilder) builder).setL2FibEntry(readData); + } + + @Nonnull + @Override + public L2FibEntryBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new L2FibEntryBuilder(); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntry readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + // Convert operational object to config. VPP does not support setting BVI (see v3po.yang) + new L2FibEntryBuilder(readValue).setBridgedVirtualInterface(null).build()); + } + + static InstanceIdentifier getCfgId( + final @Nonnull InstanceIdentifier id) { + return BridgeDomainCustomizer.getCfgId(RWUtils.cutId(id, BridgeDomain.class)).child( + L2FibTable.class).child(L2FibEntry.class, new L2FibEntryKey(id.firstKeyOf(L2FibEntry.class))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizer.java new file mode 100644 index 000000000..3f69c98df --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizer.java @@ -0,0 +1,82 @@ +/* + * 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.vppstate; + +import com.google.common.primitives.UnsignedInts; +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.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.ShowVersion; +import io.fd.vpp.jvpp.core.dto.ShowVersionReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import io.fd.vpp.jvpp.dto.ControlPing; +import io.fd.vpp.jvpp.dto.ControlPingReply; +import io.fd.vpp.jvpp.dto.JVppReply; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.VersionBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class VersionCustomizer + extends FutureJVppCustomizer + implements ReaderCustomizer, ByteDataTranslator, JvppReplyConsumer { + + public VersionCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { + super(futureJVppCore); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Version readValue) { + ((VppStateBuilder) parentBuilder).setVersion(readValue); + } + + @Nonnull + @Override + public VersionBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new VersionBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final VersionBuilder builder, + @Nonnull final ReadContext context) throws ReadFailedException { + + // Execute with timeout + final CompletionStage showVersionFuture = getFutureJVpp().showVersion(new ShowVersion()); + final ShowVersionReply reply = getReplyForRead(showVersionFuture.toCompletableFuture(), id); + + builder.setBranch(toString(reply.version)); + builder.setName(toString(reply.program)); + builder.setBuildDate(toString(reply.buildDate)); + builder.setBuildDirectory(toString(reply.buildDirectory)); + builder.setPid(getPid(id)); + } + + private Long getPid(@Nonnull final InstanceIdentifier id) throws ReadFailedException { + final CompletionStage> request = getFutureJVpp().send(new ControlPing()); + final ControlPingReply reply = (ControlPingReply)getReplyForRead(request.toCompletableFuture(), id); + return UnsignedInts.toLong(reply.vpePid); + } + + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/AclWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/AclWriterFactory.java deleted file mode 100644 index 23fc2e314..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/AclWriterFactory.java +++ /dev/null @@ -1,58 +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.honeycomb.translate.v3po; - -import static io.fd.honeycomb.translate.v3po.InterfacesWriterFactory.IETF_ACL_ID; -import static io.fd.honeycomb.translate.v3po.SubinterfaceAugmentationWriterFactory.SUBIF_IETF_ACL_ID; - -import com.google.common.collect.Sets; -import io.fd.honeycomb.translate.impl.write.GenericListWriter; -import io.fd.honeycomb.translate.v3po.interfaces.acl.IetfAclWriter; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntries; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Actions; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Matches; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class AclWriterFactory implements WriterFactory { - - public static final InstanceIdentifier ACL_ID = - InstanceIdentifier.create(AccessLists.class).child(Acl.class); - - @Override - public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { - - final InstanceIdentifier aclIdRelative = InstanceIdentifier.create(Acl.class); - - final InstanceIdentifier aceId = aclIdRelative.child(AccessListEntries.class).child(Ace.class); - final InstanceIdentifier actionsId = aceId.child(Actions.class); - final InstanceIdentifier matchesId = aceId.child(Matches.class); - final InstanceIdentifier srcPortId = matchesId.child((Class)SourcePortRange.class); - final InstanceIdentifier dstPortId = matchesId.child((Class)DestinationPortRange.class); - - registry.subtreeAddBefore(Sets.newHashSet(aceId, actionsId, matchesId, srcPortId, dstPortId), - new GenericListWriter<>(ACL_ID, new IetfAclWriter()), - Sets.newHashSet(IETF_ACL_ID, SUBIF_IETF_ACL_ID)); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/DisabledInterfacesManager.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/DisabledInterfacesManager.java deleted file mode 100644 index 9772923c3..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/DisabledInterfacesManager.java +++ /dev/null @@ -1,106 +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.honeycomb.translate.v3po; - -import com.google.common.base.Optional; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; -import io.fd.honeycomb.translate.util.read.BindingBrokerReader; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.DisabledInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.DisabledInterfacesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndex; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndexBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndexKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; - -/** - * Facade on top of {@link MappingContext} making access to {@link DisabledInterfaces} easier. - */ -public class DisabledInterfacesManager { - - private static final InstanceIdentifier - DISABLED_IFCS_ROOT = InstanceIdentifier.create(DisabledInterfaces.class); - - /** - * Read the list of currently disabled interfaces. - */ - public List getDisabledInterfaces(@Nonnull final MappingContext ctx) { - final Optional read = ctx.read(DISABLED_IFCS_ROOT); - if (read.isPresent()) { - return read.get().getDisabledInterfaceIndex().stream() - .map(DisabledInterfaceIndex::getIndex) - .collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - } - - /** - * Check whether a specific interface is disabled. - */ - public boolean isInterfaceDisabled(final int index, @Nonnull final MappingContext ctx) { - return ctx.read(getKeyedId(index)) - .isPresent(); - } - - /** - * Make a specific interface disabled. - */ - public void disableInterface(final int index, @Nonnull final MappingContext ctx) { - ctx.put(getKeyedId(index), getDisabledInterfaceIndex(index)); - } - - /** - * Remove interface disability. - */ - public void removeDisabledInterface(final int index, @Nonnull final MappingContext ctx) { - ctx.delete(getKeyedId(index)); - } - - private static DisabledInterfaceIndex getDisabledInterfaceIndex(final int index) { - return new DisabledInterfaceIndexBuilder().setIndex(index).build(); - } - - private static KeyedInstanceIdentifier getKeyedId(final int id) { - return DISABLED_IFCS_ROOT.child(DisabledInterfaceIndex.class, new DisabledInterfaceIndexKey(id)); - } - - public static final class ContextsReaderFactory implements ReaderFactory { - - @Inject - @Named("honeycomb-context") - private DataBroker contextBindingBrokerDependency; - - @Override - public void init(final ModifiableReaderRegistryBuilder registry) { - registry.add(new BindingBrokerReader<>(DISABLED_IFCS_ROOT, - contextBindingBrokerDependency, - LogicalDatastoreType.OPERATIONAL, DisabledInterfacesBuilder.class)); - } - } - -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/EgressIetfAClWriterProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/EgressIetfAClWriterProvider.java deleted file mode 100644 index f14900f03..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/EgressIetfAClWriterProvider.java +++ /dev/null @@ -1,39 +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.honeycomb.translate.v3po; - -import com.google.inject.Inject; -import com.google.inject.Provider; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManagerImpl; -import io.fd.honeycomb.translate.v3po.interfaces.acl.egress.EgressIetfAclWriter; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; - -class EgressIetfAClWriterProvider implements Provider { - - private final FutureJVppCore jvpp; - - @Inject - public EgressIetfAClWriterProvider(final FutureJVppCore jvpp) { - this.jvpp = jvpp; - } - - @Override - public EgressIetfAclWriter get() { - return new EgressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Egress)); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/IngressIetfAClWriterProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/IngressIetfAClWriterProvider.java deleted file mode 100644 index 5d97f41ae..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/IngressIetfAClWriterProvider.java +++ /dev/null @@ -1,39 +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.honeycomb.translate.v3po; - -import com.google.inject.Inject; -import com.google.inject.Provider; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManagerImpl; -import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.IngressIetfAclWriter; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; - -class IngressIetfAClWriterProvider implements Provider { - - private final FutureJVppCore jvpp; - - @Inject - public IngressIetfAClWriterProvider(final FutureJVppCore jvpp) { - this.jvpp = jvpp; - } - - @Override - public IngressIetfAclWriter get() { - return new IngressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Ingress)); - } -} 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 deleted file mode 100644 index 82909e228..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesStateReaderFactory.java +++ /dev/null @@ -1,187 +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.honeycomb.translate.v3po; - -import com.google.common.collect.Sets; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.translate.impl.read.GenericInitListReader; -import io.fd.honeycomb.translate.impl.read.GenericInitReader; -import io.fd.honeycomb.translate.impl.read.GenericListReader; -import io.fd.honeycomb.translate.impl.read.GenericReader; -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.InterfaceCustomizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.L2Customizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.ProxyArpCustomizer; -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; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Ethernet; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Gre; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Vxlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpe; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteStateInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteStateInterfaceAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteState; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class InterfacesStateReaderFactory implements ReaderFactory { - - private final NamingContext ifcNamingCtx; - private final NamingContext bdNamingCtx; - private final VppClassifierContextManager classifyContext; - private final DisabledInterfacesManager ifcDisableContext; - private final FutureJVppCore jvpp; - - static final InstanceIdentifier IFC_STATE_ID = - InstanceIdentifier.create(InterfacesState.class); - static final InstanceIdentifier IFC_ID = IFC_STATE_ID.child(Interface.class); - - @Inject - public InterfacesStateReaderFactory(final FutureJVppCore jvpp, - @Named("interface-context") final NamingContext ifcNamingCtx, - @Named("bridge-domain-context") final NamingContext bdNamingCtx, - @Named("classify-table-context") final VppClassifierContextManager classifyContext, - final DisabledInterfacesManager ifcDisableContext) { - this.jvpp = jvpp; - this.ifcNamingCtx = ifcNamingCtx; - this.bdNamingCtx = bdNamingCtx; - this.classifyContext = classifyContext; - this.ifcDisableContext = ifcDisableContext; - } - - @Override - public void init(final ModifiableReaderRegistryBuilder registry) { - // InterfacesState(Structural) - registry.addStructuralReader(IFC_STATE_ID, InterfacesStateBuilder.class); - // Interface - registry.add(new GenericInitListReader<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcNamingCtx, ifcDisableContext))); - - // v3po.yang - initVppIfcAugmentationReaders(registry, IFC_ID); - // ietf-ip.yang - 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, - final InstanceIdentifier ifcId) { - // Interface2Augmentation(Structural) - final InstanceIdentifier ifc2AugId = ifcId.augmentation(Interface2.class); - registry.addStructuralReader(ifc2AugId, Interface2Builder.class); - // Ipv4 - final InstanceIdentifier ipv4Id = ifc2AugId.child(Ipv4.class); - registry.add(new GenericReader<>(ipv4Id, new Ipv4Customizer(jvpp))); - // Address - final InstanceIdentifier

ipv4AddrId = ipv4Id.child(Address.class); - registry.add(new GenericInitListReader<>(ipv4AddrId, new Ipv4AddressCustomizer(jvpp, ifcNamingCtx))); - // Neighbor - final InstanceIdentifier neighborId = ipv4Id.child(Neighbor.class); - registry.add(new GenericListReader<>(neighborId, new Ipv4NeighbourCustomizer(jvpp))); - // Ipv6 - final InstanceIdentifier ipv6Id = ifc2AugId.child(Ipv6.class); - registry.add(new GenericReader<>(ipv6Id, new Ipv6Customizer(jvpp, ifcNamingCtx))); - } - - private void initVppIfcAugmentationReaders(final ModifiableReaderRegistryBuilder registry, - final InstanceIdentifier ifcId) { - // VppInterfaceStateAugmentation - final InstanceIdentifier vppIfcAugId = - ifcId.augmentation(VppInterfaceStateAugmentation.class); - registry.addStructuralReader(vppIfcAugId, VppInterfaceStateAugmentationBuilder.class); - // Ethernet - registry.add(new GenericInitReader<>(vppIfcAugId.child(Ethernet.class), - new EthernetCustomizer(jvpp, ifcNamingCtx))); - // Tap - registry.add(new GenericInitReader<>(vppIfcAugId.child(Tap.class), new TapCustomizer(jvpp, ifcNamingCtx))); - // VhostUser - registry.add(new GenericInitReader<>(vppIfcAugId.child(VhostUser.class), - new VhostUserCustomizer(jvpp, ifcNamingCtx))); - // Vxlan - registry.add(new GenericInitReader<>(vppIfcAugId.child(Vxlan.class), new VxlanCustomizer(jvpp, ifcNamingCtx))); - // VxlanGpe - registry.add(new GenericInitReader<>(vppIfcAugId.child(VxlanGpe.class), - new VxlanGpeCustomizer(jvpp, ifcNamingCtx))); - // Gre - registry.add(new GenericInitReader<>(vppIfcAugId.child(Gre.class), new GreCustomizer(jvpp, ifcNamingCtx))); - // L2 - registry.add(new GenericInitReader<>(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 GenericInitReader<>(aclIid.child(Ingress.class), - new AclCustomizer(jvpp, ifcNamingCtx, classifyContext))); - - // Proxy ARP - registry.add(new GenericReader<>(vppIfcAugId.child(ProxyArp.class), new ProxyArpCustomizer(jvpp, - 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 deleted file mode 100644 index 7bf5a432c..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java +++ /dev/null @@ -1,245 +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.honeycomb.translate.v3po; - -import static io.fd.honeycomb.translate.v3po.VppClassifierHoneycombWriterFactory.CLASSIFY_SESSION_ID; -import static io.fd.honeycomb.translate.v3po.VppClassifierHoneycombWriterFactory.CLASSIFY_TABLE_ID; - -import com.google.common.collect.Sets; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.translate.impl.write.GenericListWriter; -import io.fd.honeycomb.translate.impl.write.GenericWriter; -import io.fd.honeycomb.translate.v3po.interfaces.EthernetCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.GreCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.InterfaceCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.L2Customizer; -import io.fd.honeycomb.translate.v3po.interfaces.LoopbackCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.ProxyArpCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.RoutingCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.TapCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.VhostUserCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.VxlanCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.VxlanGpeCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.acl.egress.EgressIetfAclWriter; -import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.AclCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.IetfAclCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.IngressIetfAclWriter; -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; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Set; -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.ip.rev140616.Interface1; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Ethernet; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Loopback; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Routing; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.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); - public static final InstanceIdentifier VPP_IFC_AUG_ID = - 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.rev161214.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.rev161214.interfaces._interface.ietf.acl.Egress.class); - - private final FutureJVppCore jvpp; - private final IngressIetfAclWriter ingressAclWriter; - private final EgressIetfAclWriter egressAclWriter; - private final NamingContext bdNamingContext; - private final NamingContext ifcNamingContext; - private final VppClassifierContextManager classifyTableContext; - private final DisabledInterfacesManager ifcDisableContext; - - @Inject - public InterfacesWriterFactory(final FutureJVppCore vppJvppIfcDependency, - final IngressIetfAclWriter ingressAclWriter, - final EgressIetfAclWriter egressAclWriter, - @Named("bridge-domain-context") final NamingContext bridgeDomainContextDependency, - @Named("interface-context") final NamingContext interfaceContextDependency, - @Named("classify-table-context") final VppClassifierContextManager classifyTableContext, - final DisabledInterfacesManager ifcDisableContext) { - this.jvpp = vppJvppIfcDependency; - this.ingressAclWriter = ingressAclWriter; - this.egressAclWriter = egressAclWriter; - this.bdNamingContext = bridgeDomainContextDependency; - this.ifcNamingContext = interfaceContextDependency; - this.ifcDisableContext = ifcDisableContext; - this.classifyTableContext = classifyTableContext; - } - - @Override - public void init(final ModifiableWriterRegistryBuilder registry) { - // Interfaces - // Interface = - registry.add(new GenericListWriter<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcNamingContext))); - // VppInterfaceAugmentation - addVppInterfaceAgmentationWriters(IFC_ID, registry); - // Interface1 (ietf-ip augmentation) - addInterface1AugmentationWriters(IFC_ID, registry); - // SubinterfaceAugmentation - new SubinterfaceAugmentationWriterFactory(jvpp, ingressAclWriter, egressAclWriter, ifcNamingContext, bdNamingContext, - classifyTableContext).init(registry); - - addPbbAugmentationWriters(IFC_ID, registry); - } - - private void addInterface1AugmentationWriters(final InstanceIdentifier ifcId, - final ModifiableWriterRegistryBuilder registry) { - final InstanceIdentifier ifc1AugId = ifcId.augmentation(Interface1.class); - // Ipv6(after interface) = - registry.addAfter(new GenericWriter<>(ifc1AugId.child(Ipv6.class), new Ipv6Customizer(jvpp)), - ifcId); - // Ipv4(after interface) - final InstanceIdentifier ipv4Id = ifc1AugId.child(Ipv4.class); - registry.addAfter(new GenericWriter<>(ipv4Id, new Ipv4Customizer(jvpp)), - ifcId); - // Address(after Ipv4) = - final InstanceIdentifier
ipv4AddressId = ipv4Id.child(Address.class); - registry.addAfter(new GenericListWriter<>(ipv4AddressId, new Ipv4AddressCustomizer(jvpp, ifcNamingContext)), - ipv4Id); - // Neighbor(after ipv4Address) - registry.addAfter(new GenericListWriter<>(ipv4Id.child(Neighbor.class), new Ipv4NeighbourCustomizer(jvpp, - ifcNamingContext)), - ipv4AddressId); - } - - private void addVppInterfaceAgmentationWriters(final InstanceIdentifier ifcId, - final ModifiableWriterRegistryBuilder registry) { - // 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); - // 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); - // 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); - // 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); - // Loopback(Needs to be executed before Interface customizer) = - final InstanceIdentifier loopbackId = VPP_IFC_AUG_ID.child(Loopback.class); - registry.addBefore(new GenericWriter<>(loopbackId, new LoopbackCustomizer(jvpp, ifcNamingContext)), - 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); - - - final Set> specificIfcTypes = Sets.newHashSet(vhostId, vxlanGpeId, vxlanGpeId, tapId); - - // Ethernet = - 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); - // 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); - // Proxy Arp (execute after specific interface customizers) - registry.addAfter( - 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)); - - // 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.rev161214.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.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl.class); - registry.subtreeAdd( - Sets.newHashSet(accessListsIdIngress, aclIdIngress), - new GenericWriter<>(INGRESS_IETF_ACL_ID, new IetfAclCustomizer(ingressAclWriter, 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.rev161214.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.vpp.acl.rev161214.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(egressAclWriter, - 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/SubinterfaceAugmentationWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/SubinterfaceAugmentationWriterFactory.java deleted file mode 100644 index 1ef8b3865..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/SubinterfaceAugmentationWriterFactory.java +++ /dev/null @@ -1,158 +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.honeycomb.translate.v3po; - -import static io.fd.honeycomb.translate.v3po.VppClassifierHoneycombWriterFactory.CLASSIFY_SESSION_ID; -import static io.fd.honeycomb.translate.v3po.VppClassifierHoneycombWriterFactory.CLASSIFY_TABLE_ID; - -import com.google.common.collect.Sets; -import io.fd.honeycomb.translate.impl.write.GenericListWriter; -import io.fd.honeycomb.translate.impl.write.GenericWriter; -import io.fd.honeycomb.translate.v3po.interfaces.RewriteCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.SubInterfaceCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.SubInterfaceL2Customizer; -import io.fd.honeycomb.translate.v3po.interfaces.acl.egress.EgressIetfAclWriter; -import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.IngressIetfAclWriter; -import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.SubInterfaceAclCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.SubInterfaceIetfAclCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.ip.SubInterfaceIpv4AddressCustomizer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -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.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTagged; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class SubinterfaceAugmentationWriterFactory implements WriterFactory { - - private final FutureJVppCore jvpp; - private final IngressIetfAclWriter ingressAclWriter; - private final EgressIetfAclWriter egressAclWriter; - private final NamingContext ifcContext; - private final NamingContext bdContext; - private final VppClassifierContextManager classifyTableContext; - - public static final InstanceIdentifier SUB_IFC_AUG_ID = - InterfacesWriterFactory.IFC_ID.augmentation(SubinterfaceAugmentation.class); - public static final InstanceIdentifier SUB_IFC_ID = - SUB_IFC_AUG_ID.child(SubInterfaces.class).child(SubInterface.class); - public static final InstanceIdentifier L2_ID = SUB_IFC_ID.child( - L2.class); - public static final InstanceIdentifier SUBIF_ACL_ID = SUB_IFC_ID.child(Acl.class); - public static final InstanceIdentifier SUBIF_INGRESS_ACL_ID = SUBIF_ACL_ID.child(Ingress.class); - public static final InstanceIdentifier SUBIF_IETF_ACL_ID = SUB_IFC_ID.child(IetfAcl.class); - public static final InstanceIdentifier SUBIF_INGRESS_IETF_ACL_ID = SUBIF_IETF_ACL_ID.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress.class); - public static final InstanceIdentifier SUBIF_EGRESS_IETF_ACL_ID = SUBIF_IETF_ACL_ID.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress.class); - - public SubinterfaceAugmentationWriterFactory(final FutureJVppCore jvpp, - final IngressIetfAclWriter ingressAclWriter, - final EgressIetfAclWriter egressAclWriter, - final NamingContext ifcContext, final NamingContext bdContext, final VppClassifierContextManager classifyTableContext) { - this.jvpp = jvpp; - this.ingressAclWriter = ingressAclWriter; - this.egressAclWriter = egressAclWriter; - this.ifcContext = ifcContext; - this.bdContext = bdContext; - this.classifyTableContext = classifyTableContext; - } - - @Override - public void init(final ModifiableWriterRegistryBuilder registry) { - // Subinterfaces - // Subinterface(Handle only after all interface related stuff gets processed) = - registry.subtreeAddAfter( - // TODO HONEYCOMB-188 this customizer covers quite a lot of complex child nodes (maybe refactor ?) - Sets.newHashSet( - InstanceIdentifier.create(SubInterface.class).child(Tags.class), - InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class), - InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class).child( - Dot1qTag.class), - InstanceIdentifier.create(SubInterface.class).child(Match.class), - InstanceIdentifier.create(SubInterface.class).child(Match.class).child(VlanTagged.class)), - new GenericListWriter<>(SUB_IFC_ID, new SubInterfaceCustomizer(jvpp, ifcContext)), - InterfacesWriterFactory.IFC_ID); - // L2 = - registry.addAfter(new GenericWriter<>(L2_ID, new SubInterfaceL2Customizer(jvpp, ifcContext, bdContext)), - SUB_IFC_ID); - // Rewrite(also handles pushTags + pushTags/dot1qtag) = - final InstanceIdentifier rewriteId = L2_ID.child(Rewrite.class); - registry.subtreeAddAfter( - Sets.newHashSet( - InstanceIdentifier.create(Rewrite.class).child(PushTags.class), - InstanceIdentifier.create(Rewrite.class).child(PushTags.class) - .child(org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), - new GenericWriter<>(rewriteId, new RewriteCustomizer(jvpp, ifcContext)), - L2_ID); - // Ipv4(handled after L2 and L2/rewrite is done) = - final InstanceIdentifier
ipv4SubifcAddressId = SUB_IFC_ID.child(Ipv4.class).child(Address.class); - registry.addAfter(new GenericListWriter<>(ipv4SubifcAddressId, - new SubInterfaceIpv4AddressCustomizer(jvpp, ifcContext)), - rewriteId); - - // Ingress (execute after classify table and session writers) - // also handles L2Acl, Ip4Acl and Ip6Acl: - final InstanceIdentifier aclId = InstanceIdentifier.create(Ingress.class); - registry - .subtreeAddAfter( - Sets.newHashSet(aclId.child(L2Acl.class), aclId.child(Ip4Acl.class), aclId.child(Ip6Acl.class)), - new GenericWriter<>(SUBIF_INGRESS_ACL_ID, new SubInterfaceAclCustomizer(jvpp, ifcContext, 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.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress.class) - .child(AccessLists.class); - final InstanceIdentifier aclIdIngress = accessListsIdIngress.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl.class); - registry.subtreeAdd( - Sets.newHashSet(accessListsIdIngress, aclIdIngress), - new GenericWriter<>(SUBIF_INGRESS_IETF_ACL_ID, new SubInterfaceIetfAclCustomizer(ingressAclWriter, ifcContext))); - - // Egress IETF-ACL, also handles AccessLists and Acl: - final InstanceIdentifier accessListsIdEgress = InstanceIdentifier.create( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress.class) - .child(AccessLists.class); - final InstanceIdentifier aclIdEgress = accessListsIdEgress.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl.class); - registry.subtreeAdd( - Sets.newHashSet(accessListsIdEgress, aclIdEgress), - new GenericWriter<>(SUBIF_EGRESS_IETF_ACL_ID, new io.fd.honeycomb.translate.v3po.interfaces.acl.egress.SubInterfaceIetfAclCustomizer( - egressAclWriter, ifcContext))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/SubinterfaceStateAugmentationReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/SubinterfaceStateAugmentationReaderFactory.java deleted file mode 100644 index ee943bff8..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/SubinterfaceStateAugmentationReaderFactory.java +++ /dev/null @@ -1,118 +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.honeycomb.translate.v3po; - -import com.google.common.collect.Sets; -import io.fd.honeycomb.translate.impl.read.GenericInitListReader; -import io.fd.honeycomb.translate.impl.read.GenericInitReader; -import io.fd.honeycomb.translate.impl.read.GenericReader; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; -import io.fd.honeycomb.translate.v3po.interfacesstate.RewriteCustomizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.SubInterfaceCustomizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.SubInterfaceL2Customizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.acl.ingress.SubInterfaceAclCustomizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.ip.SubInterfaceIpv4AddressCustomizer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -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.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfacesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTagged; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -final class SubinterfaceStateAugmentationReaderFactory implements ReaderFactory { - - private final FutureJVppCore jvpp; - private final NamingContext ifcCtx; - private final NamingContext bdCtx; - private final VppClassifierContextManager classifyCtx; - - SubinterfaceStateAugmentationReaderFactory(final FutureJVppCore jvpp, final NamingContext ifcCtx, - final NamingContext bdCtx, - final VppClassifierContextManager classifyCtx) { - this.jvpp = jvpp; - this.ifcCtx = ifcCtx; - this.bdCtx = bdCtx; - this.classifyCtx = classifyCtx; - } - - @Override - public void init(final ModifiableReaderRegistryBuilder registry) { - // SubinterfaceStateAugmentation(Structural) - final InstanceIdentifier subIfcAugId = - InterfacesStateReaderFactory.IFC_ID.augmentation(SubinterfaceStateAugmentation.class); - registry.addStructuralReader(subIfcAugId, SubinterfaceStateAugmentationBuilder.class); - // SubInterfaces(Structural) - final InstanceIdentifier subIfcsId = subIfcAugId.child(SubInterfaces.class); - registry.addStructuralReader(subIfcsId, SubInterfacesBuilder.class); - // SubInterface(Subtree) - final InstanceIdentifier subIfcId = subIfcsId.child(SubInterface.class); - registry.subtreeAdd(Sets.newHashSet( - InstanceIdentifier.create(SubInterface.class).child(Tags.class), - InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class), - InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class).child(Dot1qTag.class), - InstanceIdentifier.create(SubInterface.class).child(Match.class), - InstanceIdentifier.create(SubInterface.class).child(Match.class).child(VlanTagged.class)), - new GenericInitListReader<>(subIfcId, new SubInterfaceCustomizer(jvpp, ifcCtx))); - // L2 - final InstanceIdentifier l2Id = subIfcId.child(L2.class); - registry.add(new GenericInitReader<>(l2Id, new SubInterfaceL2Customizer(jvpp, ifcCtx, bdCtx))); - // Rewrite(Subtree) - registry.subtreeAdd(Sets.newHashSet( - InstanceIdentifier.create(Rewrite.class).child(PushTags.class), - InstanceIdentifier.create(Rewrite.class).child(PushTags.class) - .child( - org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), - new GenericReader<>(l2Id.child(Rewrite.class), new RewriteCustomizer(jvpp, ifcCtx))); - // Ipv4(Structural) - final InstanceIdentifier ipv4Id = subIfcId.child(Ipv4.class); - registry.addStructuralReader(ipv4Id, Ipv4Builder.class); - // Address - registry.add( - new GenericInitListReader<>(ipv4Id.child(Address.class), new SubInterfaceIpv4AddressCustomizer(jvpp, ifcCtx))); - // Acl(Structural) - final InstanceIdentifier aclIid = subIfcId.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 GenericInitReader<>(aclIid.child(Ingress.class), - new SubInterfaceAclCustomizer(jvpp, ifcCtx, classifyCtx))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/V3poModule.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/V3poModule.java deleted file mode 100644 index d1bf234a3..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/V3poModule.java +++ /dev/null @@ -1,92 +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.honeycomb.translate.v3po; - -import com.google.inject.AbstractModule; -import com.google.inject.multibindings.Multibinder; -import com.google.inject.name.Names; -import io.fd.honeycomb.notification.ManagedNotificationProducer; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.v3po.cfgattrs.V3poConfiguration; -import io.fd.honeycomb.translate.v3po.interfaces.acl.egress.EgressIetfAclWriter; -import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.IngressIetfAclWriter; -import io.fd.honeycomb.translate.v3po.notification.InterfaceChangeNotificationProducer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManagerImpl; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriterFactory; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import net.jmob.guice.conf.core.ConfigurationModule; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class V3poModule extends AbstractModule { - - private static final Logger LOG = LoggerFactory.getLogger(V3poModule.class); - - @Override - protected void configure() { - LOG.debug("Installing V3PO module"); - install(ConfigurationModule.create()); - requestInjection(V3poConfiguration.class); - - // TODO HONEYCOMB-173 put into constants - // Naming contexts - bind(NamingContext.class) - .annotatedWith(Names.named("interface-context")) - .toInstance(new NamingContext("interface-", "interface-context")); - bind(NamingContext.class) - .annotatedWith(Names.named("bridge-domain-context")) - .toInstance(new NamingContext("bridge-domain-", "bridge-domain-context")); - bind(VppClassifierContextManager.class) - .annotatedWith(Names.named("classify-table-context")) - .toInstance(new VppClassifierContextManagerImpl("classify-table-")); - - // Executor needed for keepalives - bind(ScheduledExecutorService.class).toInstance(Executors.newScheduledThreadPool(1)); - - // Utils - bind(IngressIetfAclWriter.class).toProvider(IngressIetfAClWriterProvider.class); - bind(EgressIetfAclWriter.class).toProvider(EgressIetfAClWriterProvider.class); - // Context utility for deleted interfaces - bind(DisabledInterfacesManager.class).toInstance(new DisabledInterfacesManager()); - - // Readers - final Multibinder readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); - readerFactoryBinder.addBinding().to(InterfacesStateReaderFactory.class); - readerFactoryBinder.addBinding().to(VppStateHoneycombReaderFactory.class); - readerFactoryBinder.addBinding().to(VppClassifierReaderFactory.class); - // Expose disabled interfaces in operational data - readerFactoryBinder.addBinding().to(DisabledInterfacesManager.ContextsReaderFactory.class); - // Expose vpp-classfier-context interfaces in operational data - readerFactoryBinder.addBinding().to(VppClassifierContextManagerImpl.ContextsReaderFactory.class); - - // Writers - final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); - writerFactoryBinder.addBinding().to(InterfacesWriterFactory.class); - writerFactoryBinder.addBinding().to(VppHoneycombWriterFactory.class); - writerFactoryBinder.addBinding().to(VppClassifierHoneycombWriterFactory.class); - writerFactoryBinder.addBinding().to(AclWriterFactory.class); - - // Notifications - final Multibinder notifiersBinder = - Multibinder.newSetBinder(binder(), ManagedNotificationProducer.class); - notifiersBinder.addBinding().to(InterfaceChangeNotificationProducer.class); - LOG.info("Module V3PO successfully configured"); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppClassifierHoneycombWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppClassifierHoneycombWriterFactory.java deleted file mode 100644 index 66cd13244..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppClassifierHoneycombWriterFactory.java +++ /dev/null @@ -1,66 +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.honeycomb.translate.v3po; - -import static io.fd.honeycomb.translate.v3po.InterfacesWriterFactory.ACL_ID; - -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.translate.impl.write.GenericListWriter; -import io.fd.honeycomb.translate.v3po.vppclassifier.ClassifySessionWriter; -import io.fd.honeycomb.translate.v3po.vppclassifier.ClassifyTableWriter; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -public final class VppClassifierHoneycombWriterFactory implements WriterFactory { - - public static final InstanceIdentifier CLASSIFY_TABLE_ID = - InstanceIdentifier.create(VppClassifier.class).child(ClassifyTable.class); - - public static final InstanceIdentifier CLASSIFY_SESSION_ID = - CLASSIFY_TABLE_ID.child(ClassifySession.class); - - private final FutureJVppCore jvpp; - private final VppClassifierContextManager classifyTableContext; - - @Inject - public VppClassifierHoneycombWriterFactory(@Nonnull final FutureJVppCore jvpp, - @Named("classify-table-context") @Nonnull final VppClassifierContextManager classifyTableContext) { - this.jvpp = jvpp; - this.classifyTableContext = classifyTableContext; - } - - @Override - public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { - // Ordering here is: First create table, then create sessions and then assign as ACL - // ClassifyTable - registry.addBefore( - new GenericListWriter<>(CLASSIFY_TABLE_ID, new ClassifyTableWriter(jvpp, classifyTableContext)), - CLASSIFY_SESSION_ID); - // ClassifyTableSession - registry.addBefore( - new GenericListWriter<>(CLASSIFY_SESSION_ID, new ClassifySessionWriter(jvpp, classifyTableContext)), - ACL_ID); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppClassifierReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppClassifierReaderFactory.java deleted file mode 100644 index b7a67c853..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppClassifierReaderFactory.java +++ /dev/null @@ -1,60 +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.honeycomb.translate.v3po; - -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.translate.impl.read.GenericInitListReader; -import io.fd.honeycomb.translate.impl.read.GenericListReader; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; -import io.fd.honeycomb.translate.v3po.vppclassifier.ClassifySessionReader; -import io.fd.honeycomb.translate.v3po.vppclassifier.ClassifyTableReader; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -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.classifier.rev161214.VppClassifierState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class VppClassifierReaderFactory implements ReaderFactory { - - private final FutureJVppCore jvpp; - private final VppClassifierContextManager classifyCtx; - - @Inject - public VppClassifierReaderFactory(final FutureJVppCore jvpp, - @Named("classify-table-context") final VppClassifierContextManager classifyCtx) { - this.jvpp = jvpp; - this.classifyCtx = classifyCtx; - } - - @Override - public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { - // VppClassifierState - final InstanceIdentifier vppStateId = InstanceIdentifier.create(VppClassifierState.class); - registry.addStructuralReader(vppStateId, VppClassifierStateBuilder.class); - // ClassifyTable - final InstanceIdentifier classTblId = vppStateId.child(ClassifyTable.class); - registry.add(new GenericInitListReader<>(classTblId, new ClassifyTableReader(jvpp, classifyCtx))); - // ClassifySession - final InstanceIdentifier classSesId = classTblId.child(ClassifySession.class); - registry.add(new GenericListReader<>(classSesId, new ClassifySessionReader(jvpp, classifyCtx))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppHoneycombWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppHoneycombWriterFactory.java deleted file mode 100644 index 7a59eede8..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppHoneycombWriterFactory.java +++ /dev/null @@ -1,81 +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.honeycomb.translate.v3po; - -import static io.fd.honeycomb.translate.v3po.InterfacesWriterFactory.L2_ID; - -import com.google.common.collect.Sets; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.translate.impl.write.GenericListWriter; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.v3po.vpp.ArpTerminationTableEntryCustomizer; -import io.fd.honeycomb.translate.v3po.vpp.BridgeDomainCustomizer; -import io.fd.honeycomb.translate.v3po.vpp.L2FibEntryCustomizer; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Vpp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.ArpTerminationTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -public final class VppHoneycombWriterFactory implements WriterFactory { - - private final FutureJVppCore jvpp; - private final NamingContext bdContext; - private final NamingContext ifcContext; - - @Inject - public VppHoneycombWriterFactory(final FutureJVppCore vppJvppWriterDependency, - @Named("bridge-domain-context") final NamingContext bridgeDomainContextVppDependency, - @Named("interface-context") final NamingContext interfaceContextVppDependency) { - this.jvpp = vppJvppWriterDependency; - this.bdContext = bridgeDomainContextVppDependency; - this.ifcContext = interfaceContextVppDependency; - } - - @Override - public void init(final ModifiableWriterRegistryBuilder registry) { - // Vpp has no handlers - // BridgeDomains has no handlers - // BridgeDomain = - final InstanceIdentifier bdId = - InstanceIdentifier.create(Vpp.class).child(BridgeDomains.class).child(BridgeDomain.class); - registry.add(new GenericListWriter<>(bdId, new BridgeDomainCustomizer(jvpp, bdContext))); - // L2FibTable has no handlers - // L2FibEntry(handled after BridgeDomain and L2 of ifc and subifc) = - final InstanceIdentifier l2FibEntryId = bdId.child(L2FibTable.class).child(L2FibEntry.class); - registry.addAfter( - new GenericListWriter<>(l2FibEntryId, new L2FibEntryCustomizer(jvpp, bdContext, ifcContext)), - Sets.newHashSet( - bdId, - L2_ID, - SubinterfaceAugmentationWriterFactory.L2_ID)); - // ArpTerminationTable has no handlers - // ArpTerminationTableEntry(handled after BridgeDomain) = - final InstanceIdentifier arpEntryId = - bdId.child(ArpTerminationTable.class).child(ArpTerminationTableEntry.class); - registry.addAfter( - new GenericListWriter<>(arpEntryId, new ArpTerminationTableEntryCustomizer(jvpp, bdContext)), - bdId); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppStateHoneycombReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppStateHoneycombReaderFactory.java deleted file mode 100644 index 67c435b16..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/VppStateHoneycombReaderFactory.java +++ /dev/null @@ -1,90 +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.honeycomb.translate.v3po; - -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.translate.impl.read.GenericInitListReader; -import io.fd.honeycomb.translate.impl.read.GenericReader; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; -import io.fd.honeycomb.translate.util.read.KeepaliveReaderWrapper; -import io.fd.honeycomb.translate.v3po.vppstate.BridgeDomainCustomizer; -import io.fd.honeycomb.translate.v3po.vppstate.L2FibEntryCustomizer; -import io.fd.honeycomb.translate.v3po.vppstate.VersionCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.ReadTimeoutException; -import io.fd.honeycomb.translate.vpp.util.VppStatusListener; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.ScheduledExecutorService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class VppStateHoneycombReaderFactory implements ReaderFactory { - - private final FutureJVppCore jVpp; - private final NamingContext ifcCtx; - private final NamingContext bdCtx; - private final ScheduledExecutorService keepaliveExecutor; - private final VppStatusListener vppStatusListener; - - @Inject - public VppStateHoneycombReaderFactory(final FutureJVppCore jVpp, - @Named("interface-context") final NamingContext ifcCtx, - @Named("bridge-domain-context") final NamingContext bdCtx, - final ScheduledExecutorService keepaliveExecutorDependency, - final VppStatusListener vppStatusListener) { - this.jVpp = jVpp; - this.ifcCtx = ifcCtx; - this.bdCtx = bdCtx; - this.keepaliveExecutor = keepaliveExecutorDependency; - this.vppStatusListener = vppStatusListener; - } - - @Override - public void init(final ModifiableReaderRegistryBuilder registry) { - // VppState(Structural) - final InstanceIdentifier vppStateId = InstanceIdentifier.create(VppState.class); - registry.addStructuralReader(vppStateId, VppStateBuilder.class); - // Version - // Wrap with keepalive reader to detect connection issues - // Relying on VersionCustomizer to provide a "timing out read" - registry.add(new KeepaliveReaderWrapper<>( - new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp)), - keepaliveExecutor, ReadTimeoutException.class, 30, vppStatusListener)); - // BridgeDomains(Structural) - final InstanceIdentifier bridgeDomainsId = vppStateId.child(BridgeDomains.class); - registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class); - // BridgeDomain - final InstanceIdentifier bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class); - registry.add(new GenericInitListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdCtx))); - // L2FibTable(Structural) - final InstanceIdentifier l2FibTableId = bridgeDomainId.child(L2FibTable.class); - registry.addStructuralReader(l2FibTableId, L2FibTableBuilder.class); - // L2FibEntry - registry.add(new GenericInitListReader<>(l2FibTableId.child(L2FibEntry.class), - new L2FibEntryCustomizer(jVpp, bdCtx, ifcCtx))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/cfgattrs/V3poConfiguration.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/cfgattrs/V3poConfiguration.java deleted file mode 100644 index 9cf5b4d5d..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/cfgattrs/V3poConfiguration.java +++ /dev/null @@ -1,24 +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.honeycomb.translate.v3po.cfgattrs; - -import net.jmob.guice.conf.core.BindConfig; -import net.jmob.guice.conf.core.Syntax; - -@BindConfig(value = "v3po", syntax = Syntax.JSON) -public class V3poConfiguration { -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/EthernetCustomizer.java deleted file mode 100644 index 856366f2b..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/EthernetCustomizer.java +++ /dev/null @@ -1,58 +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.honeycomb.translate.v3po.interfaces; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Ethernet; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class EthernetCustomizer extends FutureJVppCustomizer implements WriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class); - - public EthernetCustomizer(final FutureJVppCore vppApi) { - super(vppApi); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ethernet dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.warn("Unsupported, ignoring configuration {}", dataAfter); - // VPP API does not support setting MTU - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ethernet dataBefore, @Nonnull final Ethernet dataAfter, - @Nonnull final WriteContext writeContext) { - LOG.warn("Unsupported, ignoring configuration {}", dataAfter); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ethernet dataBefore, @Nonnull final WriteContext writeContext) { - LOG.warn("Unsupported, ignoring configuration delete {}", id); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/GreCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/GreCustomizer.java deleted file mode 100644 index 146d97c5c..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/GreCustomizer.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2016 Intel 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; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.net.InetAddresses; -import io.fd.honeycomb.translate.vpp.util.AbstractInterfaceTypeCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.GreAddDelTunnel; -import io.fd.vpp.jvpp.core.dto.GreAddDelTunnelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.net.InetAddress; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; -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.rev161214.GreTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class GreCustomizer extends AbstractInterfaceTypeCustomizer implements JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(GreCustomizer.class); - private final NamingContext interfaceContext; - - public GreCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - } - - private static GreAddDelTunnel getGreTunnelRequest(final byte isAdd, final byte[] srcAddr, final byte[] dstAddr, - final int outerFibId, final byte isIpv6) { - final GreAddDelTunnel greAddDelTunnel = new GreAddDelTunnel(); - greAddDelTunnel.isAdd = isAdd; - greAddDelTunnel.srcAddress = srcAddr; - greAddDelTunnel.dstAddress = dstAddr; - greAddDelTunnel.outerFibId = outerFibId; - greAddDelTunnel.isIpv6 = isIpv6; - return greAddDelTunnel; - } - - @Override - protected Class getExpectedInterfaceType() { - return GreTunnel.class; - } - - @Override - protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Gre dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - - createGreTunnel(id, swIfName, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Gre dataBefore, - @Nonnull final Gre dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException.UpdateFailedException { - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, - new UnsupportedOperationException("Gre tunnel update is not supported")); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Gre dataBefore, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - deleteGreTunnel(id, swIfName, dataBefore, writeContext); - } - - private void createGreTunnel(final InstanceIdentifier id, final String swIfName, final Gre gre, - final WriteContext writeContext) throws WriteFailedException { - final byte isIpv6 = (byte) (isIpv6(gre) - ? 1 - : 0); - final InetAddress srcAddress = InetAddresses.forString(getAddressString(gre.getSrc())); - final InetAddress dstAddress = InetAddresses.forString(getAddressString(gre.getDst())); - - int outerFibId = gre.getOuterFibId().intValue(); - - LOG.debug("Setting gre tunnel for interface: {}. Gre: {}", swIfName, gre); - final CompletionStage greAddDelTunnelReplyCompletionStage = - getFutureJVpp().greAddDelTunnel(getGreTunnelRequest((byte) 1 /* is add */, srcAddress.getAddress(), - dstAddress.getAddress(), outerFibId, isIpv6)); - - final GreAddDelTunnelReply reply = - getReplyForCreate(greAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, gre); - LOG.debug("Gre tunnel set successfully for: {}, gre: {}", swIfName, gre); - if (interfaceContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { - // VPP keeps gre tunnels present even after they are delete(reserving ID for next tunnel) - // This may cause inconsistencies in mapping context when configuring tunnels like this: - // 1. Add tunnel 2. Delete tunnel 3. Read interfaces (reserved mapping e.g. gre_tunnel0 -> 6 - // will get into mapping context) 4. Add tunnel (this will add another mapping with the same - // reserved ID and context is invalid) - // That's why a check has to be performed here removing mapping gre_tunnel0 -> 6 mapping and storing - // new name for that ID - final String formerName = interfaceContext.getName(reply.swIfIndex, writeContext.getMappingContext()); - LOG.debug("Removing updated mapping of a gre tunnel, id: {}, former name: {}, new name: {}", - reply.swIfIndex, formerName, swIfName); - interfaceContext.removeName(formerName, writeContext.getMappingContext()); - } - // Add new interface to our interface context - interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); - } - - private boolean isIpv6(final Gre gre) { - if (gre.getSrc().getIpv4Address() == null) { - checkArgument(gre.getDst().getIpv4Address() == null, "Inconsistent ip addresses: %s, %s", gre.getSrc(), - gre.getDst()); - return true; - } else { - checkArgument(gre.getDst().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", gre.getSrc(), - gre.getDst()); - return false; - } - } - - private String getAddressString(final IpAddress addr) { - return addr.getIpv4Address() == null - ? addr.getIpv6Address().getValue() - : addr.getIpv4Address().getValue(); - } - - private void deleteGreTunnel(final InstanceIdentifier id, final String swIfName, final Gre gre, - final WriteContext writeContext) throws WriteFailedException { - final byte isIpv6 = (byte) (isIpv6(gre) - ? 1 - : 0); - final InetAddress srcAddress = InetAddresses.forString(getAddressString(gre.getSrc())); - final InetAddress dstAddress = InetAddresses.forString(getAddressString(gre.getDst())); - - int outerFibId = gre.getOuterFibId().intValue(); - - LOG.debug("Deleting gre tunnel for interface: {}. Gre: {}", swIfName, gre); - final CompletionStage greAddDelTunnelReplyCompletionStage = - getFutureJVpp().greAddDelTunnel(getGreTunnelRequest((byte) 0 /* is add */, srcAddress.getAddress(), - dstAddress.getAddress(), outerFibId, isIpv6)); - - getReplyForDelete(greAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); - LOG.debug("Gre tunnel deleted successfully for: {}, gre: {}", swIfName, gre); - // Remove interface from our interface context - interfaceContext.removeName(swIfName, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/InterconnectionWriteUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/InterconnectionWriteUtils.java deleted file mode 100644 index 7d2d28c90..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/InterconnectionWriteUtils.java +++ /dev/null @@ -1,159 +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.honeycomb.translate.v3po.interfaces; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.SwInterfaceSetL2Bridge; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2BridgeReply; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Xconnect; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2XconnectReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBased; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBased; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class providing Interconnection CUD support. - */ -final class InterconnectionWriteUtils implements JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(InterconnectionWriteUtils.class); - - private final FutureJVppCore futureJVppCore; - private final NamingContext interfaceContext; - private final NamingContext bridgeDomainContext; - - InterconnectionWriteUtils(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext, - @Nonnull final NamingContext bridgeDomainContext) { - this.futureJVppCore = requireNonNull(futureJVppCore, "futureJVppCore should not be null"); - this.interfaceContext = requireNonNull(interfaceContext, "interfaceContext should not be null"); - this.bridgeDomainContext = requireNonNull(bridgeDomainContext, "bridgeDomainContext should not be null"); - } - - void setInterconnection(final InstanceIdentifier id, final int swIfIndex, - final String ifcName, final Interconnection ic, final WriteContext writeContext) - throws WriteFailedException { - - if (ic == null) { // TODO in case of update we should delete interconnection - LOG.trace("Interconnection is not set. Skipping"); - } else if (ic instanceof XconnectBased) { - setXconnectBasedL2(id, swIfIndex, ifcName, (XconnectBased) ic, writeContext, (byte) 1 /*enable*/); - } else if (ic instanceof BridgeBased) { - setBridgeBasedL2(id, swIfIndex, ifcName, (BridgeBased) ic, writeContext, (byte) 1 /*enable*/); - } else { - // Choices&cases are not data objects, so they cannot have a dedicated Reader/Writer - // This choice is already from augment, so its not possible to augment augmented choice - LOG.error("Unable to handle Interconnection of type {}", ic.getClass()); - throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass()); - } - } - - void deleteInterconnection(final InstanceIdentifier id, final int swIfIndex, - final String ifcName, final Interconnection ic, final WriteContext writeContext) - throws WriteFailedException { - - if (ic == null) { // TODO in case of update we should delete interconnection - LOG.trace("Interconnection is not set. Skipping"); - } else if (ic instanceof XconnectBased) { - setXconnectBasedL2(id, swIfIndex, ifcName, (XconnectBased) ic, writeContext, (byte) 0 /*disable*/); - } else if (ic instanceof BridgeBased) { - setBridgeBasedL2(id, swIfIndex, ifcName, (BridgeBased) ic, writeContext, (byte) 0 /*disable*/); - } else { - LOG.error("Unable to delete Interconnection of type {}", ic.getClass()); - throw new WriteFailedException(id, "Unable to delete Interconnection of type " + ic.getClass()); - } - } - - private void setBridgeBasedL2(final InstanceIdentifier id, final int swIfIndex, - final String ifcName, final BridgeBased bb, - final WriteContext writeContext, final byte enabled) throws WriteFailedException { - LOG.debug("Setting bridge based interconnection(bridge-domain={}) for interface: {}", bb.getBridgeDomain(), - ifcName); - - String bdName = bb.getBridgeDomain(); - - int bdId = bridgeDomainContext.getIndex(bdName, writeContext.getMappingContext()); - checkArgument(bdId > 0, "Unable to set Interconnection for Interface: %s, bridge domain: %s does not exist", - ifcName, bdName); - - byte bvi = bb.isBridgedVirtualInterface() - ? (byte) 1 - : (byte) 0; - byte shg = 0; - if (bb.getSplitHorizonGroup() != null) { - shg = bb.getSplitHorizonGroup().byteValue(); - } - - final CompletionStage swInterfaceSetL2BridgeReplyCompletionStage = futureJVppCore - .swInterfaceSetL2Bridge(getL2BridgeRequest(swIfIndex, bdId, shg, bvi, enabled)); - getReplyForWrite(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture(), id); - - LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName, bb); - } - - private SwInterfaceSetL2Bridge getL2BridgeRequest(final int swIfIndex, final int bdId, final byte shg, - final byte bvi, final byte enabled) { - final SwInterfaceSetL2Bridge swInterfaceSetL2Bridge = new SwInterfaceSetL2Bridge(); - swInterfaceSetL2Bridge.rxSwIfIndex = swIfIndex; - swInterfaceSetL2Bridge.bdId = bdId; - swInterfaceSetL2Bridge.shg = shg; - swInterfaceSetL2Bridge.bvi = bvi; - swInterfaceSetL2Bridge.enable = enabled; - return swInterfaceSetL2Bridge; - } - - private void setXconnectBasedL2(final InstanceIdentifier id, final int swIfIndex, - final String ifcName, final XconnectBased ic, - final WriteContext writeContext, final byte enabled) throws WriteFailedException { - String outSwIfName = ic.getXconnectOutgoingInterface(); - LOG.debug("Setting xconnect based interconnection(outgoing ifc={}) for interface: {}", outSwIfName, ifcName); - - int outSwIfIndex = interfaceContext.getIndex(outSwIfName, writeContext.getMappingContext()); - checkArgument(outSwIfIndex > 0, - "Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist", - ifcName, outSwIfIndex); - - final CompletionStage swInterfaceSetL2XconnectReplyCompletionStage = - futureJVppCore - .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, enabled)); - getReplyForWrite(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture(), id); - LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName, ic); - } - - private SwInterfaceSetL2Xconnect getL2XConnectRequest(final int rxIfc, final int txIfc, - final byte enabled) { - - final SwInterfaceSetL2Xconnect swInterfaceSetL2Xconnect = new SwInterfaceSetL2Xconnect(); - swInterfaceSetL2Xconnect.enable = enabled; - swInterfaceSetL2Xconnect.rxSwIfIndex = rxIfc; - swInterfaceSetL2Xconnect.txSwIfIndex = txIfc; - return swInterfaceSetL2Xconnect; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizer.java deleted file mode 100644 index 17b48f628..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizer.java +++ /dev/null @@ -1,121 +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.honeycomb.translate.v3po.interfaces; - -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.SwInterfaceSetFlags; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Ietf interface write customizer that only caches interface objects for child writers - */ -public class InterfaceCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); - private final NamingContext interfaceContext; - - public InterfaceCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Interface dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - setInterface(id, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Interface dataBefore, - @Nonnull final Interface dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - updateInterface(id, dataBefore, dataAfter, writeContext); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Interface dataBefore, - @Nonnull final WriteContext writeContext) { - // Nothing to be done here, customizers for specific interface types e.g. vxlan handle the delete - } - - private void setInterface(final InstanceIdentifier id, final Interface swIf, - final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Setting interface: {} to: {}", id, swIf); - setInterfaceAttributes(id, swIf, swIf.getName(), writeContext); - } - - private void setInterfaceAttributes(final InstanceIdentifier id, final Interface swIf, - final String swIfName, final WriteContext writeContext) - throws WriteFailedException { - - setInterfaceFlags(id, swIfName, interfaceContext.getIndex(swIfName, writeContext.getMappingContext()), - swIf.isEnabled() - ? (byte) 1 - : (byte) 0); - } - - private void updateInterface(final InstanceIdentifier id, - final Interface dataBefore, - final Interface dataAfter, final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Updating interface:{} to: {}", id, dataAfter); - setInterfaceAttributes(id, dataAfter, dataAfter.getName(), writeContext); - } - - private void setInterfaceFlags(final InstanceIdentifier id, final String swIfName, final int swIfIndex, - final byte enabled) throws WriteFailedException { - final CompletionStage swInterfaceSetFlagsReplyFuture = - getFutureJVpp().swInterfaceSetFlags( - getSwInterfaceSetFlagsInput(swIfIndex, enabled, (byte) 0 /* deleted */)); - - LOG.debug("Updating interface flags for: {}, index: {}, enabled: {}", swIfName, swIfIndex, enabled); - - getReplyForWrite(swInterfaceSetFlagsReplyFuture.toCompletableFuture(), id); - LOG.debug("Interface flags updated successfully for: {}, index: {}, enabled: {}", - swIfName, swIfIndex, enabled); - } - - private SwInterfaceSetFlags getSwInterfaceSetFlagsInput(final int swIfIndex, final byte enabled, - final byte deleted) { - final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags(); - swInterfaceSetFlags.swIfIndex = swIfIndex; - swInterfaceSetFlags.adminUpDown = enabled; - swInterfaceSetFlags.linkUpDown = enabled; - swInterfaceSetFlags.deleted = deleted; - return swInterfaceSetFlags; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/L2Customizer.java deleted file mode 100644 index cf9da357d..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/L2Customizer.java +++ /dev/null @@ -1,89 +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.honeycomb.translate.v3po.interfaces; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.v3po.rev161214.interfaces._interface.L2; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class L2Customizer extends FutureJVppCustomizer implements WriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class); - private final NamingContext interfaceContext; - private final InterconnectionWriteUtils icWriteUtils; - - public L2Customizer(final FutureJVppCore vppApi, final NamingContext interfaceContext, - final NamingContext bridgeDomainContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - this.icWriteUtils = new InterconnectionWriteUtils(vppApi, interfaceContext, bridgeDomainContext); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - final String ifcName = id.firstKeyOf(Interface.class).getName(); - final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); - setL2(id, swIfc, ifcName, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataBefore, - @Nonnull final L2 dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - final String ifcName = id.firstKeyOf(Interface.class).getName(); - final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); - // No update, again calling set - setL2(id, swIfc, ifcName, dataAfter, writeContext); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifcName = id.firstKeyOf(Interface.class).getName(); - final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); - deleteL2(id, swIfc, ifcName, dataBefore, writeContext); - } - - private void setL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final L2 l2, - final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Setting L2 for interface: {}", ifcName); - // Nothing besides interconnection here - icWriteUtils.setInterconnection(id, swIfIndex, ifcName, l2.getInterconnection(), writeContext); - } - - private void deleteL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final L2 l2Before, - final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Deleting L2 for interface: {}", ifcName); - // Nothing besides interconnection here - icWriteUtils.deleteInterconnection(id, swIfIndex, ifcName, l2Before.getInterconnection(), writeContext); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/LoopbackCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/LoopbackCustomizer.java deleted file mode 100644 index 47a71750d..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/LoopbackCustomizer.java +++ /dev/null @@ -1,112 +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.honeycomb.translate.v3po.interfaces; - -import io.fd.honeycomb.translate.vpp.util.AbstractInterfaceTypeCustomizer; -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.core.dto.CreateLoopback; -import io.fd.vpp.jvpp.core.dto.CreateLoopbackReply; -import io.fd.vpp.jvpp.core.dto.DeleteLoopback; -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.InterfaceType; -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.rev161214.interfaces._interface.Loopback; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class LoopbackCustomizer extends AbstractInterfaceTypeCustomizer - implements MacTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(LoopbackCustomizer.class); - private final NamingContext interfaceContext; - - public LoopbackCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - } - - @Override - protected Class getExpectedInterfaceType() { - return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Loopback.class; - } - - @Override - protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Loopback dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String ifcName = id.firstKeyOf(Interface.class).getName(); - createLoopback(id, ifcName, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Loopback dataBefore, - @Nonnull final Loopback dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, - new UnsupportedOperationException("Modification of loopback interface is not supported")); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Loopback dataBefore, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String ifcName = id.firstKeyOf(Interface.class).getName(); - - final int index; - try { - index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); - } catch (IllegalArgumentException e) { - throw new WriteFailedException.DeleteFailedException(id, e); - } - - deleteLoopback(id, ifcName, index, dataBefore, writeContext); - } - - private void createLoopback(final InstanceIdentifier id, final String swIfName, final Loopback loopback, - final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Setting loopback interface: {}. Loopback: {}", swIfName, loopback); - - final CreateLoopback createLoopback = new CreateLoopback(); - if (loopback.getMac() != null) { - createLoopback.macAddress = parseMac(loopback.getMac().getValue()); - } - final CreateLoopbackReply reply = - getReplyForCreate(getFutureJVpp().createLoopback(createLoopback).toCompletableFuture(), id, loopback); - - LOG.debug("Loopback set successfully for: {}, loopback: {}", swIfName, loopback); - // Add new interface to our interface context - interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); - } - - private void deleteLoopback(final InstanceIdentifier id, final String swIfName, final int index, - final Loopback dataBefore, final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Deleting loopback interface: {}. Loopback: {}", swIfName, dataBefore); - final DeleteLoopback deleteLoopback = new DeleteLoopback(); - deleteLoopback.swIfIndex = index; - getReplyForDelete(getFutureJVpp().deleteLoopback(deleteLoopback).toCompletableFuture(), id); - LOG.debug("Loopback deleted successfully for: {}, loopback: {}", swIfName, dataBefore); - // Remove deleted interface from interface context - interfaceContext.removeName(swIfName, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizer.java deleted file mode 100644 index 43a34cdcd..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizer.java +++ /dev/null @@ -1,108 +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.honeycomb.translate.v3po.interfaces; - -import com.google.common.net.InetAddresses; -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.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ProxyArpAddDel; -import io.fd.vpp.jvpp.core.dto.ProxyArpAddDelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.net.InetAddress; -import java.util.concurrent.Future; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArp; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCustomizer, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class); - - public ProxyArpCustomizer(final FutureJVppCore vppApi) { - super(vppApi); - } - - @Override - public void writeCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataAfter, - @Nonnull WriteContext writeContext) throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - createProxyArp(getProxyArpRequestFuture(id, swIfName, dataAfter, (byte) 1 /* 1 is add */), id, dataAfter); - } - - @Override - public void updateCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataBefore, - @Nonnull ProxyArp dataAfter, @Nonnull WriteContext writeContext) - throws WriteFailedException.UpdateFailedException { - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, - new UnsupportedOperationException("ARP proxy update is not supported")); - } - - @Override - public void deleteCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataBefore, - @Nonnull WriteContext writeContext) throws WriteFailedException { - - final String swIfName = id.firstKeyOf(Interface.class).getName(); - deleteProxyArp(getProxyArpRequestFuture(id, swIfName, dataBefore, (byte) 0 /* 0 is delete */), id); - } - - private Future getProxyArpRequestFuture(InstanceIdentifier id, String swIfName, - ProxyArp proxyArp, byte operation) - throws WriteFailedException { - LOG.debug("Setting Proxy ARP settings for interface: {}", swIfName); - final InetAddress srcAddress = InetAddresses.forString(getv4AddressString(proxyArp.getLowAddr())); - final InetAddress dstAddress = InetAddresses.forString(getv4AddressString(proxyArp.getHighAddr())); - final int vrfId = proxyArp.getVrfId().intValue(); - return getFutureJVpp().proxyArpAddDel( - getProxyArpConfRequest(operation, srcAddress.getAddress(), dstAddress.getAddress(), vrfId)) - .toCompletableFuture(); - } - - private void createProxyArp(final Future future, final InstanceIdentifier identifier, - final ProxyArp data) - throws WriteFailedException { - final ProxyArpAddDelReply reply = getReplyForCreate(future, identifier, data); - LOG.debug("Proxy ARP setting create successful, with reply context:", reply.context); - } - - private void deleteProxyArp(final Future future, final InstanceIdentifier identifier) - throws WriteFailedException { - final ProxyArpAddDelReply reply = getReplyForDelete(future, identifier); - LOG.debug("Proxy ARP setting delete successful, with reply context:", reply.context); - } - - private static ProxyArpAddDel getProxyArpConfRequest(final byte isAdd, final byte[] lAddr, final byte[] hAddr, - final int vrfId) { - - final ProxyArpAddDel proxyArpAddDel = new ProxyArpAddDel(); - proxyArpAddDel.isAdd = isAdd; - proxyArpAddDel.lowAddress = lAddr; - proxyArpAddDel.hiAddress = hAddr; - proxyArpAddDel.vrfId = vrfId; - return proxyArpAddDel; - } - - private String getv4AddressString(@Nonnull final Ipv4Address addr) { - return addr.getValue(); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/RewriteCustomizer.java deleted file mode 100644 index 204f5e152..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/RewriteCustomizer.java +++ /dev/null @@ -1,136 +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.honeycomb.translate.v3po.interfaces; - -import com.google.common.base.Preconditions; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.vpp.util.TagRewriteOperation; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.L2InterfaceVlanTagRewrite; -import io.fd.vpp.jvpp.core.dto.L2InterfaceVlanTagRewriteReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.List; -import java.util.concurrent.CompletionStage; -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.vlan.rev161214._802dot1q; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.RewriteBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer Customizer responsible for vlan tag rewrite.
Sends {@code l2_interface_vlan_tag_rewrite} message to - * VPP.
Equivalent of invoking {@code vppctl set interface l2 tag-rewrite} command. - */ -public class RewriteCustomizer extends FutureJVppCustomizer - implements WriterCustomizer, ByteDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class); - private final NamingContext interfaceContext; - - public RewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void writeCurrentAttributes(final InstanceIdentifier id, final Rewrite dataAfter, - final WriteContext writeContext) - throws WriteFailedException { - final String subifName = getSubInterfaceName(id); - setTagRewrite(id, subifName, dataAfter, writeContext); - } - - private static String getSubInterfaceName(final InstanceIdentifier id) { - return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), - Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier())); - } - - private void setTagRewrite(final InstanceIdentifier id, final String ifname, final Rewrite rewrite, - final WriteContext writeContext) throws WriteFailedException { - final int swIfIndex = interfaceContext.getIndex(ifname, writeContext.getMappingContext()); - LOG.debug("Setting tag rewrite for interface {}(id=): {}", ifname, swIfIndex, rewrite); - - final CompletionStage replyCompletionStage = - getFutureJVpp().l2InterfaceVlanTagRewrite(getTagRewriteRequest(swIfIndex, rewrite)); - - getReplyForWrite(replyCompletionStage.toCompletableFuture(), id); - LOG.debug("Tag rewrite for interface {}(id=) set successfully: {}", ifname, swIfIndex, rewrite); - } - - private L2InterfaceVlanTagRewrite getTagRewriteRequest(final int swIfIndex, final Rewrite rewrite) { - final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite(); - request.swIfIndex = swIfIndex; - request.pushDot1Q = booleanToByte(_802dot1q.class == rewrite.getVlanType()); - - final List pushTags = rewrite.getPushTags(); - final Short popTags = rewrite.getPopTags(); - - final int numberOfTagsToPop = popTags == null - ? 0 - : popTags.intValue(); - final int numberOfTagsToPush = pushTags == null - ? 0 - : pushTags.size(); - - request.vtrOp = TagRewriteOperation.get(numberOfTagsToPop, numberOfTagsToPush).ordinal(); - - if (numberOfTagsToPush > 0) { - for (final PushTags tag : pushTags) { - if (tag.getIndex() == 0) { - request.tag1 = tag.getDot1qTag().getVlanId().getValue(); - } else { - request.tag2 = tag.getDot1qTag().getVlanId().getValue(); - } - } - } - - LOG.debug("Generated tag rewrite request: {}", request); - return request; - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Rewrite dataBefore, - @Nonnull final Rewrite dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String subifName = getSubInterfaceName(id); - setTagRewrite(id, subifName, dataAfter, writeContext); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Rewrite dataBefore, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String subifName = getSubInterfaceName(id); - - LOG.debug("Disabling tag rewrite for interface {}", subifName); - final Rewrite rewrite = new RewriteBuilder().build(); // rewrite without push and pops will cause delete - setTagRewrite(id, subifName, rewrite, writeContext); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizer.java deleted file mode 100644 index 05ecf3648..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizer.java +++ /dev/null @@ -1,122 +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.honeycomb.translate.v3po.interfaces; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.SwInterfaceSetTable; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetTableReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -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.v3po.rev161214.interfaces._interface.Routing; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RoutingCustomizer extends FutureJVppCustomizer implements WriterCustomizer, JvppReplyConsumer, - ByteDataTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(RoutingCustomizer.class); - private final NamingContext interfaceContext; - - public RoutingCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - final String ifName = id.firstKeyOf(Interface.class).getName(); - setRouting(id, ifName, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Routing dataBefore, @Nonnull final Routing dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - final String ifName = id.firstKeyOf(Interface.class).getName(); - setRouting(id, ifName, dataAfter, writeContext); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Routing dataBefore, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - disableRouting(id, ifName, writeContext); - } - - private void setRouting(@Nonnull final InstanceIdentifier id, @Nonnull final String name, - @Nonnull final Routing rt, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final int swIfc = interfaceContext.getIndex(name, writeContext.getMappingContext()); - LOG.debug("Setting routing for interface: {}, {}. Routing: {}", name, swIfc, rt); - checkArgument(rt.getIpv4VrfId() != null || rt.getIpv6VrfId() != null, "No vrf-id given"); - - setVrfId(id, swIfc, rt.getIpv4VrfId(), false); - setVrfId(id, swIfc, rt.getIpv6VrfId(), true); - - LOG.debug("Routing set successfully for interface: {}, {}, routing: {}", name, swIfc, rt); - } - - private void setVrfId(final InstanceIdentifier id, final int swIfc, final Long vrfId, boolean isIp6) - throws WriteFailedException { - if (vrfId == null) { - return; - } - final CompletionStage cs = getFutureJVpp() - .swInterfaceSetTable(getInterfaceSetTableRequest(swIfc, booleanToByte(isIp6), vrfId.intValue())); - getReplyForWrite(cs.toCompletableFuture(), id); - } - - /** - * In this case, there is no such thing as delete routing,only thing that can be done is to disable it by setting - * default value 0 - */ - private void disableRouting(final InstanceIdentifier id, final String name, - final WriteContext writeContext) throws WriteFailedException { - final int swIfc = interfaceContext.getIndex(name, writeContext.getMappingContext()); - LOG.debug("Disabling routing for interface: {}, {}.", name, swIfc); - - getReplyForDelete(getFutureJVpp() - .swInterfaceSetTable(getInterfaceSetTableRequest(swIfc, (byte) 0, 0)).toCompletableFuture(), id); - LOG.debug("Routing for interface: {}, {} successfully disabled", name, swIfc); - - } - - private SwInterfaceSetTable getInterfaceSetTableRequest(final int swIfc, final byte isIpv6, final int vrfId) { - final SwInterfaceSetTable swInterfaceSetTable = new SwInterfaceSetTable(); - swInterfaceSetTable.isIpv6 = isIpv6; - swInterfaceSetTable.swIfIndex = swIfc; - swInterfaceSetTable.vrfId = vrfId; - return swInterfaceSetTable; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizer.java deleted file mode 100644 index 364567772..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizer.java +++ /dev/null @@ -1,193 +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.honeycomb.translate.v3po.interfaces; - -import static com.google.common.base.Preconditions.checkState; -import static io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils.getNumberOfTags; -import static io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils.getSubInterfaceName; - -import com.google.common.base.Preconditions; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.CreateSubif; -import io.fd.vpp.jvpp.core.dto.CreateSubifReply; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlags; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan; -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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1ad; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.MatchType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.Default; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTagged; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer Customizer responsible for sub interface creation.
Sends {@code create_subif} message to VPP.
- * Equivalent of invoking {@code vppclt create subif} command. - */ -public class SubInterfaceCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class); - private final NamingContext interfaceContext; - - public SubInterfaceCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final SubInterface dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String superIfName = id.firstKeyOf(Interface.class).getName(); - createSubInterface(id, superIfName, dataAfter, writeContext); - } - - private void createSubInterface(final InstanceIdentifier id, @Nonnull final String superIfName, - @Nonnull final SubInterface subInterface, final WriteContext writeContext) - throws WriteFailedException { - final int superIfIndex = interfaceContext.getIndex(superIfName, writeContext.getMappingContext()); - final CompletionStage createSubifReplyCompletionStage = - getFutureJVpp().createSubif(getCreateSubifRequest(subInterface, superIfIndex)); - - final CreateSubifReply reply = - getReplyForCreate(createSubifReplyCompletionStage.toCompletableFuture(), id, subInterface); - - setInterfaceState(id, reply.swIfIndex, booleanToByte(subInterface.isEnabled())); - interfaceContext.addName(reply.swIfIndex, - getSubInterfaceName(superIfName, Math.toIntExact(subInterface.getIdentifier())), - writeContext.getMappingContext()); - LOG.debug("Sub interface created successfully for: {}, subInterface: {}", superIfName, subInterface); - } - - private CreateSubif getCreateSubifRequest(@Nonnull final SubInterface subInterface, final int swIfIndex) { - // TODO HONEYCOMB-183 add validation - CreateSubif request = new CreateSubif(); - request.subId = Math.toIntExact(subInterface.getIdentifier().intValue()); - request.swIfIndex = swIfIndex; - - final int numberOfTags = getNumberOfTags(subInterface.getTags()); - switch (numberOfTags) { - case 0: - request.noTags = 1; - break; - case 1: - request.oneTag = 1; - break; - case 2: - request.twoTags = 1; - break; - } - request.dot1Ad = booleanToByte(_802dot1ad.class == subInterface.getVlanType()); - - // TODO HONEYCOMB-183 match should be mandatory - final MatchType matchType = subInterface.getMatch().getMatchType(); - request.exactMatch = - booleanToByte(matchType instanceof VlanTagged && ((VlanTagged) matchType).isMatchExactTags()); - request.defaultSub = booleanToByte(matchType instanceof Default); - - if (numberOfTags > 0) { - for (final Tag tag : subInterface.getTags().getTag()) { - if (tag.getIndex() == 0) { - setOuterTag(request, tag); - } else if (tag.getIndex() == 1) { - setInnerTag(request, tag); - } - } - } - return request; - } - - private void setOuterTag(final CreateSubif request, final Tag outerTag) { - checkState(SVlan.class == outerTag.getDot1qTag().getTagType(), "Service Tag expected at index 0"); - final Dot1qTag.VlanId vlanId = outerTag.getDot1qTag().getVlanId(); - - request.outerVlanId = dot1qVlanIdToShort(vlanId.getDot1qVlanId()); - request.outerVlanIdAny = booleanToByte(Dot1qTag.VlanId.Enumeration.Any.equals(vlanId.getEnumeration())); - } - - private void setInnerTag(final CreateSubif request, final Tag innerTag) { - checkState(CVlan.class == innerTag.getDot1qTag().getTagType(), "Customer Tag expected at index 1"); - final Dot1qTag.VlanId vlanId = innerTag.getDot1qTag().getVlanId(); - - request.innerVlanId = dot1qVlanIdToShort(vlanId.getDot1qVlanId()); - request.innerVlanIdAny = booleanToByte(Dot1qTag.VlanId.Enumeration.Any.equals(vlanId.getEnumeration())); - } - - private static short dot1qVlanIdToShort(@Nullable Dot1qVlanId dot1qVlanId) { - if (dot1qVlanId == null) { - return 0; // tell VPP that optional argument is missing - } else { - return dot1qVlanId.getValue().shortValue(); - } - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final SubInterface dataBefore, @Nonnull final SubInterface dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String subIfaceName = getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), - Math.toIntExact(dataAfter.getIdentifier())); - setInterfaceState(id, interfaceContext.getIndex(subIfaceName, writeContext.getMappingContext()), - booleanToByte(dataAfter.isEnabled())); - } - - private void setInterfaceState(final InstanceIdentifier id, final int swIfIndex, final byte enabled) - throws WriteFailedException { - final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags(); - swInterfaceSetFlags.swIfIndex = swIfIndex; - swInterfaceSetFlags.adminUpDown = enabled; - - final CompletionStage swInterfaceSetFlagsReplyFuture = - getFutureJVpp().swInterfaceSetFlags(swInterfaceSetFlags); - - LOG.debug("Updating interface state for interface if={}, enabled: {}", swIfIndex, enabled); - - SwInterfaceSetFlagsReply reply = - getReplyForWrite(swInterfaceSetFlagsReplyFuture.toCompletableFuture(), id); - LOG.debug("Interface state updated successfully for interface index: {}, enabled: {}, ctxId: {}", - swIfIndex, enabled, reply.context); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final SubInterface dataBefore, - @Nonnull final WriteContext writeContext) - throws WriteFailedException.DeleteFailedException { - throw new UnsupportedOperationException("Sub interface delete is not supported"); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2Customizer.java deleted file mode 100644 index a485d0749..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2Customizer.java +++ /dev/null @@ -1,100 +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.honeycomb.translate.v3po.interfaces; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for writing vlan sub interface l2 configuration - */ -public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements WriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class); - private final NamingContext interfaceContext; - private final InterconnectionWriteUtils icWriterUtils; - - public SubInterfaceL2Customizer(final FutureJVppCore vppApi, final NamingContext interfaceContext, - final NamingContext bridgeDomainContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - this.icWriterUtils = new InterconnectionWriteUtils(vppApi, interfaceContext, bridgeDomainContext); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext); - } - - private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - return SubInterfaceUtils - .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataBefore, - @Nonnull final L2 dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - // Setting L2 to new values - setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2 dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - deleteL2(id, subInterfaceIndex, subInterfaceName, dataBefore, writeContext); - } - - private void setL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final L2 l2, - final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Setting L2 for sub-interface: {}", ifcName); - icWriterUtils.setInterconnection(id, swIfIndex, ifcName, l2.getInterconnection(), writeContext); - } - - private void deleteL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final L2 l2Before, - final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Deleting L2 for sub-interface: {}", ifcName); - icWriterUtils.deleteInterconnection(id, swIfIndex, ifcName, l2Before.getInterconnection(), writeContext); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/TapCustomizer.java deleted file mode 100644 index ef3fd32ff..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/TapCustomizer.java +++ /dev/null @@ -1,182 +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.honeycomb.translate.v3po.interfaces; - -import io.fd.honeycomb.translate.vpp.util.AbstractInterfaceTypeCustomizer; -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.core.dto.TapConnect; -import io.fd.vpp.jvpp.core.dto.TapConnectReply; -import io.fd.vpp.jvpp.core.dto.TapDelete; -import io.fd.vpp.jvpp.core.dto.TapDeleteReply; -import io.fd.vpp.jvpp.core.dto.TapModify; -import io.fd.vpp.jvpp.core.dto.TapModifyReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; -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.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TapCustomizer extends AbstractInterfaceTypeCustomizer implements MacTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class); - private final NamingContext interfaceContext; - - public TapCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - } - - @Override - protected Class getExpectedInterfaceType() { - return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap.class; - } - - @Override - protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Tap dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String ifcName = id.firstKeyOf(Interface.class).getName(); - createTap(id, ifcName, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Tap dataBefore, - @Nonnull final Tap dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String ifcName = id.firstKeyOf(Interface.class).getName(); - - final int index; - try { - index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); - } catch (IllegalArgumentException e) { - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); - } - - modifyTap(id, ifcName, index, dataBefore, dataAfter); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Tap dataBefore, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String ifcName = id.firstKeyOf(Interface.class).getName(); - - final int index; - try { - index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); - } catch (IllegalArgumentException e) { - throw new WriteFailedException.DeleteFailedException(id, e); - } - - deleteTap(id, ifcName, index, dataBefore, writeContext); - } - - private void createTap(final InstanceIdentifier id, final String swIfName, final Tap tap, - final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Setting tap interface: {}. Tap: {}", swIfName, tap); - final CompletionStage tapConnectFuture = getFutureJVpp() - .tapConnect(getTapConnectRequest(tap.getTapName(), tap.getMac(), tap.getDeviceInstance())); - final TapConnectReply reply = getReplyForCreate(tapConnectFuture.toCompletableFuture(), id, tap); - LOG.debug("Tap set successfully for: {}, tap: {}", swIfName, tap); - // Add new interface to our interface context - interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); - } - - private void modifyTap(final InstanceIdentifier id, final String swIfName, final int index, - final Tap tapBefore, final Tap tapAfter) throws WriteFailedException { - LOG.debug("Modifying tap interface: {}. Tap: {}", swIfName, tapAfter); - final CompletionStage vxlanAddDelTunnelReplyCompletionStage = - getFutureJVpp() - .tapModify(getTapModifyRequest(tapAfter.getTapName(), index, tapAfter.getMac(), - tapAfter.getDeviceInstance())); - getReplyForUpdate(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, tapBefore, tapAfter); - LOG.debug("Tap modified successfully for: {}, tap: {}", swIfName, tapAfter); - } - - private void deleteTap(final InstanceIdentifier id, final String swIfName, final int index, - final Tap dataBefore, final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Deleting tap interface: {}. Tap: {}", swIfName, dataBefore); - final CompletionStage vxlanAddDelTunnelReplyCompletionStage = - getFutureJVpp().tapDelete(getTapDeleteRequest(index)); - getReplyForDelete(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); - LOG.debug("Tap deleted successfully for: {}, tap: {}", swIfName, dataBefore); - // Remove deleted interface from interface context - interfaceContext.removeName(swIfName, writeContext.getMappingContext()); - } - - private TapConnect getTapConnectRequest(final String tapName, final PhysAddress mac, final Long deviceInstance) { - final TapConnect tapConnect = new TapConnect(); - tapConnect.tapName = tapName.getBytes(); - - if (mac == null) { - tapConnect.useRandomMac = 1; - tapConnect.macAddress = new byte[6]; - } else { - tapConnect.useRandomMac = 0; - tapConnect.macAddress = parseMac(mac.getValue()); - } - - if (deviceInstance == null) { - tapConnect.renumber = 0; - } else { - tapConnect.renumber = 1; - tapConnect.customDevInstance = Math.toIntExact(deviceInstance); - } - - return tapConnect; - } - - private TapModify getTapModifyRequest(final String tapName, final int swIndex, final PhysAddress mac, - final Long deviceInstance) { - final TapModify tapConnect = new TapModify(); - tapConnect.tapName = tapName.getBytes(); - tapConnect.swIfIndex = swIndex; - - if (mac == null) { - tapConnect.useRandomMac = 1; - tapConnect.macAddress = new byte[6]; - } else { - tapConnect.useRandomMac = 0; - tapConnect.macAddress = parseMac(mac.getValue()); - } - - if (deviceInstance == null) { - tapConnect.renumber = 0; - } else { - tapConnect.renumber = 1; - tapConnect.customDevInstance = Math.toIntExact(deviceInstance); - } - - return tapConnect; - } - - private TapDelete getTapDeleteRequest(final int swIndex) { - final TapDelete tapConnect = new TapDelete(); - tapConnect.swIfIndex = swIndex; - return tapConnect; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VhostUserCustomizer.java deleted file mode 100644 index 4f834c239..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VhostUserCustomizer.java +++ /dev/null @@ -1,157 +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.honeycomb.translate.v3po.interfaces; - -import com.google.common.base.Preconditions; -import io.fd.honeycomb.translate.vpp.util.AbstractInterfaceTypeCustomizer; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.CreateVhostUserIf; -import io.fd.vpp.jvpp.core.dto.CreateVhostUserIfReply; -import io.fd.vpp.jvpp.core.dto.DeleteVhostUserIf; -import io.fd.vpp.jvpp.core.dto.DeleteVhostUserIfReply; -import io.fd.vpp.jvpp.core.dto.ModifyVhostUserIf; -import io.fd.vpp.jvpp.core.dto.ModifyVhostUserIfReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; -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.rev161214.VhostUserRole; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer Customizer responsible for passing vhost user interface CRD operations to VPP - */ -public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer - implements ByteDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class); - private final NamingContext interfaceContext; - - public VhostUserCustomizer(@Nonnull final FutureJVppCore vppApi, @Nonnull final NamingContext interfaceContext) { - super(vppApi); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - protected Class getExpectedInterfaceType() { - return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser.class; - } - - @Override - protected final void writeInterface(@Nonnull final InstanceIdentifier id, - @Nonnull final VhostUser dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - createVhostUserIf(id, swIfName, dataAfter, writeContext); - } - - private void createVhostUserIf(final InstanceIdentifier id, final String swIfName, - final VhostUser vhostUser, final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Creating vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); - - final CompletionStage createVhostUserIfReplyCompletionStage = - getFutureJVpp().createVhostUserIf(getCreateVhostUserIfRequest(vhostUser)); - final CreateVhostUserIfReply reply = - getReplyForCreate(createVhostUserIfReplyCompletionStage.toCompletableFuture(), id, vhostUser); - LOG.debug("Vhost user interface created successfully for: {}, vhostUser: {}", swIfName, vhostUser); - // Add new interface to our interface context - interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); - } - - private CreateVhostUserIf getCreateVhostUserIfRequest(final VhostUser vhostUser) { - CreateVhostUserIf request = new CreateVhostUserIf(); - request.isServer = booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())); - request.sockFilename = vhostUser.getSocket().getBytes(); - // TODO HONEYCOMB-177 expose device instance attribute just like for TAP - request.renumber = 0; - request.customDevInstance = 0; - request.useCustomMac = 0; - request.macAddress = new byte[]{}; - return request; - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final VhostUser dataBefore, @Nonnull final VhostUser dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - modifyVhostUserIf(id, swIfName, dataBefore, dataAfter, writeContext); - } - - private void modifyVhostUserIf(final InstanceIdentifier id, final String swIfName, - final VhostUser vhostUserBefore, final VhostUser vhostUserAfter, - final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Updating vhost user interface: name={}, vhostUser={}", swIfName, vhostUserAfter); - final CompletionStage modifyVhostUserIfReplyCompletionStage = - getFutureJVpp() - .modifyVhostUserIf(getModifyVhostUserIfRequest(vhostUserAfter, - interfaceContext.getIndex(swIfName, writeContext.getMappingContext()))); - - getReplyForUpdate(modifyVhostUserIfReplyCompletionStage.toCompletableFuture(), id, vhostUserBefore, - vhostUserAfter); - LOG.debug("Vhost user interface updated successfully for: {}, vhostUser: {}", swIfName, vhostUserAfter); - } - - private ModifyVhostUserIf getModifyVhostUserIfRequest(final VhostUser vhostUser, final int swIfIndex) { - ModifyVhostUserIf request = new ModifyVhostUserIf(); - request.isServer = booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())); - request.sockFilename = vhostUser.getSocket().getBytes(); - // TODO HONEYCOMB-177 - request.renumber = 0; - request.customDevInstance = 0; - request.swIfIndex = swIfIndex; - return request; - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final VhostUser dataBefore, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - deleteVhostUserIf(id, swIfName, dataBefore, writeContext); - } - - private void deleteVhostUserIf(final InstanceIdentifier id, final String swIfName, - final VhostUser vhostUser, final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Deleting vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); - final CompletionStage deleteVhostUserIfReplyCompletionStage = - getFutureJVpp().deleteVhostUserIf(getDeleteVhostUserIfRequest( - interfaceContext.getIndex(swIfName, writeContext.getMappingContext()))); - - getReplyForDelete(deleteVhostUserIfReplyCompletionStage.toCompletableFuture(), id); - LOG.debug("Vhost user interface deleted successfully for: {}, vhostUser: {}", swIfName, vhostUser); - // Remove interface from our interface context - interfaceContext.removeName(swIfName, writeContext.getMappingContext()); - } - - private DeleteVhostUserIf getDeleteVhostUserIfRequest(final int swIfIndex) { - DeleteVhostUserIf request = new DeleteVhostUserIf(); - request.swIfIndex = swIfIndex; - return request; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanCustomizer.java deleted file mode 100644 index 4248a1f1c..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanCustomizer.java +++ /dev/null @@ -1,192 +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.honeycomb.translate.v3po.interfaces; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.net.InetAddresses; -import io.fd.honeycomb.translate.v3po.DisabledInterfacesManager; -import io.fd.honeycomb.translate.vpp.util.AbstractInterfaceTypeCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.VxlanAddDelTunnel; -import io.fd.vpp.jvpp.core.dto.VxlanAddDelTunnelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.net.InetAddress; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; -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.rev161214.VxlanTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer implements JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class); - - private final NamingContext interfaceNamingContext; - private final DisabledInterfacesManager interfaceDisableContext; - - public VxlanCustomizer(@Nonnull final FutureJVppCore vppApi, - @Nonnull final NamingContext interfaceNamingContext, - @Nonnull final DisabledInterfacesManager interfaceDisableContext) { - super(vppApi); - this.interfaceNamingContext = interfaceNamingContext; - this.interfaceDisableContext = interfaceDisableContext; - } - - @Override - protected Class getExpectedInterfaceType() { - return VxlanTunnel.class; - } - - @Override - protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Vxlan dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - createVxlanTunnel(id, swIfName, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Vxlan dataBefore, - @Nonnull final Vxlan dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException.UpdateFailedException { - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, - new UnsupportedOperationException("Vxlan tunnel update is not supported")); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Vxlan dataBefore, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - deleteVxlanTunnel(id, swIfName, dataBefore, writeContext); - } - - private void createVxlanTunnel(final InstanceIdentifier id, final String swIfName, final Vxlan vxlan, - final WriteContext writeContext) - throws WriteFailedException { - final byte isIpv6 = (byte) (isIpv6(vxlan) - ? 1 - : 0); - final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc())); - final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst())); - - int encapVrfId = vxlan.getEncapVrfId().intValue(); - int vni = vxlan.getVni().getValue().intValue(); - - LOG.debug("Setting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan); - final CompletionStage vxlanAddDelTunnelReplyCompletionStage = - getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 1 /* is add */, srcAddress.getAddress(), - dstAddress.getAddress(), encapVrfId, -1, vni, isIpv6)); - - final VxlanAddDelTunnelReply reply = - getReplyForCreate(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, vxlan); - LOG.debug("Vxlan tunnel set successfully for: {}, vxlan: {}", swIfName, vxlan); - if (interfaceNamingContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { - // VPP keeps vxlan tunnels present even after they are delete(reserving ID for next tunnel) - // This may cause inconsistencies in mapping context when configuring tunnels like this: - // 1. Add tunnel 2. Delete tunnel 3. Read interfaces (reserved mapping e.g. vxlan_tunnel0 -> 6 - // will get into mapping context) 4. Add tunnel (this will add another mapping with the same - // reserved ID and context is invalid) - // That's why a check has to be performed here removing mapping vxlan_tunnel0 -> 6 mapping and storing - // new name for that ID - final String formerName = interfaceNamingContext.getName(reply.swIfIndex, writeContext.getMappingContext()); - LOG.debug("Removing updated mapping of a vxlan tunnel, id: {}, former name: {}, new name: {}", - reply.swIfIndex, formerName, swIfName); - interfaceNamingContext.removeName(formerName, writeContext.getMappingContext()); - - } - - // Removing disability of an interface in case a vxlan tunnel formerly deleted is being reused in VPP - // further details in above comment - if (interfaceDisableContext.isInterfaceDisabled(reply.swIfIndex, writeContext.getMappingContext())) { - LOG.debug("Removing disability of vxlan tunnel, id: {}, name: {}", reply.swIfIndex, swIfName); - interfaceDisableContext.removeDisabledInterface(reply.swIfIndex, writeContext.getMappingContext()); - } - - // Add new interface to our interface context - interfaceNamingContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); - } - - private boolean isIpv6(final Vxlan vxlan) { - if (vxlan.getSrc().getIpv4Address() == null) { - checkArgument(vxlan.getDst().getIpv4Address() == null, "Inconsistent ip addresses: %s, %s", vxlan.getSrc(), - vxlan.getDst()); - return true; - } else { - checkArgument(vxlan.getDst().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", vxlan.getSrc(), - vxlan.getDst()); - return false; - } - } - - private String getAddressString(final IpAddress addr) { - return addr.getIpv4Address() == null - ? addr.getIpv6Address().getValue() - : addr.getIpv4Address().getValue(); - } - - private void deleteVxlanTunnel(final InstanceIdentifier id, final String swIfName, final Vxlan vxlan, - final WriteContext writeContext) throws WriteFailedException { - final byte isIpv6 = (byte) (isIpv6(vxlan) - ? 1 - : 0); - final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc())); - final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst())); - - int encapVrfId = vxlan.getEncapVrfId().intValue(); - int vni = vxlan.getVni().getValue().intValue(); - - LOG.debug("Deleting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan); - final CompletionStage vxlanAddDelTunnelReplyCompletionStage = - getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 0 /* is add */, srcAddress.getAddress(), - dstAddress.getAddress(), encapVrfId, -1, vni, isIpv6)); - - getReplyForDelete(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); - LOG.debug("Vxlan tunnel deleted successfully for: {}, vxlan: {}", swIfName, vxlan); - - final int index = interfaceNamingContext.getIndex(swIfName, writeContext.getMappingContext()); - // Mark this interface as disabled to not include it in operational reads - // because VPP will keep the interface there - LOG.debug("Marking vxlan tunnel as disabled, id: {}, name: {}", index, swIfName); - interfaceDisableContext.disableInterface(index, writeContext.getMappingContext()); - // Remove interface from our interface naming context - interfaceNamingContext.removeName(swIfName, writeContext.getMappingContext()); - } - - private static VxlanAddDelTunnel getVxlanTunnelRequest(final byte isAdd, final byte[] srcAddr, final byte[] dstAddr, - final int encapVrfId, - final int decapNextIndex, final int vni, final byte isIpv6) { - final VxlanAddDelTunnel vxlanAddDelTunnel = new VxlanAddDelTunnel(); - vxlanAddDelTunnel.isAdd = isAdd; - vxlanAddDelTunnel.srcAddress = srcAddr; - vxlanAddDelTunnel.dstAddress = dstAddr; - vxlanAddDelTunnel.encapVrfId = encapVrfId; - vxlanAddDelTunnel.vni = vni; - vxlanAddDelTunnel.decapNextIndex = decapNextIndex; - vxlanAddDelTunnel.isIpv6 = isIpv6; - return vxlanAddDelTunnel; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanGpeCustomizer.java deleted file mode 100644 index 3e1891e0f..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanGpeCustomizer.java +++ /dev/null @@ -1,194 +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.honeycomb.translate.v3po.interfaces; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.net.InetAddresses; -import io.fd.honeycomb.translate.v3po.DisabledInterfacesManager; -import io.fd.honeycomb.translate.vpp.util.AbstractInterfaceTypeCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.VxlanGpeAddDelTunnel; -import io.fd.vpp.jvpp.core.dto.VxlanGpeAddDelTunnelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.net.InetAddress; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; -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.rev161214.VxlanGpeTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer implements JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class); - private final NamingContext interfaceNamingContext; - private final DisabledInterfacesManager interfaceDisableContext; - - public VxlanGpeCustomizer(@Nonnull final FutureJVppCore vppApi, - @Nonnull final NamingContext interfaceNamingContext, - @Nonnull final DisabledInterfacesManager interfaceDisableContext) { - super(vppApi); - this.interfaceNamingContext = interfaceNamingContext; - this.interfaceDisableContext = interfaceDisableContext; - } - - @Override - protected Class getExpectedInterfaceType() { - return VxlanGpeTunnel.class; - } - - @Override - protected final void writeInterface(@Nonnull final InstanceIdentifier id, - @Nonnull final VxlanGpe dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - createVxlanGpeTunnel(id, swIfName, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final VxlanGpe dataBefore, - @Nonnull final VxlanGpe dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException.UpdateFailedException { - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, - new UnsupportedOperationException("VxlanGpe tunnel update is not supported")); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final VxlanGpe dataBefore, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - deleteVxlanGpeTunnel(id, swIfName, dataBefore, writeContext); - } - - private void createVxlanGpeTunnel(final InstanceIdentifier id, final String swIfName, - final VxlanGpe vxlanGpe, final WriteContext writeContext) - throws WriteFailedException { - final byte isIpv6 = (byte) (isIpv6(vxlanGpe) - ? 1 - : 0); - final InetAddress Local = InetAddresses.forString(getAddressString(vxlanGpe.getLocal())); - final InetAddress Remote = InetAddresses.forString(getAddressString(vxlanGpe.getRemote())); - - int vni = vxlanGpe.getVni().getValue().intValue(); - byte protocol = (byte) vxlanGpe.getNextProtocol().getIntValue(); - int encapVrfId = vxlanGpe.getEncapVrfId().intValue(); - int decapVrfId = vxlanGpe.getDecapVrfId().intValue(); - - LOG.debug("Setting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, vxlanGpe); - final CompletionStage VxlanGpeAddDelTunnelReplyCompletionStage = - getFutureJVpp().vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 1 /* is add */, Local.getAddress(), - Remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); - - final VxlanGpeAddDelTunnelReply reply = - getReplyForCreate(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, vxlanGpe); - LOG.debug("VxlanGpe tunnel set successfully for: {}, VxlanGpe: {}", swIfName, vxlanGpe); - if (interfaceNamingContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { - final String formerName = interfaceNamingContext.getName(reply.swIfIndex, writeContext.getMappingContext()); - LOG.debug("Removing updated mapping of a vxlan-gpe tunnel, id: {}, former name: {}, new name: {}", - reply.swIfIndex, formerName, swIfName); - interfaceNamingContext.removeName(formerName, writeContext.getMappingContext()); - } - - // Removing disability of an interface in case a vxlan-gpe tunnel formerly deleted is being reused in VPP - // further details in above comment - if (interfaceDisableContext.isInterfaceDisabled(reply.swIfIndex, writeContext.getMappingContext())) { - LOG.debug("Removing disability of vxlan tunnel, id: {}, name: {}", reply.swIfIndex, swIfName); - interfaceDisableContext.removeDisabledInterface(reply.swIfIndex, writeContext.getMappingContext()); - } - - // Add new interface to our interface context - interfaceNamingContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); - } - - private boolean isIpv6(final VxlanGpe vxlanGpe) { - if (vxlanGpe.getLocal().getIpv4Address() == null) { - checkArgument(vxlanGpe.getRemote().getIpv4Address() == null, "Inconsistent ip addresses: %s, %s", - vxlanGpe.getLocal(), - vxlanGpe.getRemote()); - return true; - } else { - checkArgument(vxlanGpe.getRemote().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", - vxlanGpe.getLocal(), - vxlanGpe.getRemote()); - return false; - } - } - - private String getAddressString(final IpAddress addr) { - return addr.getIpv4Address() == null - ? addr.getIpv6Address().getValue() - : addr.getIpv4Address().getValue(); - } - - private void deleteVxlanGpeTunnel(final InstanceIdentifier id, final String swIfName, - final VxlanGpe vxlanGpe, final WriteContext writeContext) - throws WriteFailedException { - final byte isIpv6 = (byte) (isIpv6(vxlanGpe) - ? 1 - : 0); - final InetAddress local = InetAddresses.forString(getAddressString(vxlanGpe.getLocal())); - final InetAddress remote = InetAddresses.forString(getAddressString(vxlanGpe.getRemote())); - - int vni = vxlanGpe.getVni().getValue().intValue(); - byte protocol = (byte) vxlanGpe.getNextProtocol().getIntValue(); - int encapVrfId = vxlanGpe.getEncapVrfId().intValue(); - int decapVrfId = vxlanGpe.getDecapVrfId().intValue(); - - LOG.debug("Deleting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, vxlanGpe); - final CompletionStage VxlanGpeAddDelTunnelReplyCompletionStage = - getFutureJVpp() - .vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 0 /* is delete */, local.getAddress(), - remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); - getReplyForDelete(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); - final int index = interfaceNamingContext.getIndex(swIfName, writeContext.getMappingContext()); - // Mark this interface as disabled to not include it in operational reads - // because VPP will keep the interface there - LOG.debug("Marking vxlan tunnel as disabled, id: {}, name: {}", index, swIfName); - interfaceDisableContext.disableInterface(index, writeContext.getMappingContext()); - // Remove interface from our interface naming context - interfaceNamingContext.removeName(swIfName, writeContext.getMappingContext()); - } - - private static VxlanGpeAddDelTunnel getVxlanGpeTunnelRequest(final byte isAdd, final byte[] local, - final byte[] remote, - final int vni, final byte protocol, - final int encapVrfId, final int decapVrfId, - final byte isIpv6) { - final VxlanGpeAddDelTunnel VxlanGpeAddDelTunnel = new VxlanGpeAddDelTunnel(); - VxlanGpeAddDelTunnel.isAdd = isAdd; - VxlanGpeAddDelTunnel.local = local; - VxlanGpeAddDelTunnel.remote = remote; - VxlanGpeAddDelTunnel.vni = vni; - VxlanGpeAddDelTunnel.protocol = protocol; - VxlanGpeAddDelTunnel.encapVrfId = encapVrfId; - VxlanGpeAddDelTunnel.decapVrfId = decapVrfId; - VxlanGpeAddDelTunnel.isIpv6 = isIpv6; - return VxlanGpeAddDelTunnel; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/IetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/IetfAclWriter.java deleted file mode 100644 index e46f53ebf..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/IetfAclWriter.java +++ /dev/null @@ -1,106 +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.honeycomb.translate.v3po.interfaces.acl; - -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.Optional; -import java.util.stream.Stream; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer customizer responsible for Access Control Lists management. Does not send any messages to VPP. All the config - * data are stored in HC and used when acl is assigned/unassigned to/from an interface. - * - * ACLs that are currently assigned to an interface cannot be updated/deleted. - */ -public class IetfAclWriter implements ListWriterCustomizer { - - public static final InstanceIdentifier ACL_ID = - InstanceIdentifier.create(AccessLists.class); - - private static final Logger LOG = LoggerFactory.getLogger(IetfAclWriter.class); - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Creating ACL: iid={} dataAfter={}", id, dataAfter); - - // no vpp call, just updates DataTree - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataBefore, - @Nonnull final Acl dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Updating ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter); - - if (isAssigned(dataAfter, writeContext)) { - throw new WriteFailedException(id, - String.format("Failed to update data at %s: acl %s is already assigned", id, dataAfter)); - } - - LOG.debug("Updating unassigned ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter); - - // no vpp call, just updates DataTree - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Acl dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Deleting ACL: iid={} dataBefore={}", id, dataBefore); - - if (isAssigned(dataBefore, writeContext)) { - throw new WriteFailedException(id, - String.format("Failed to delete data at %s: acl %s is already assigned", id, dataBefore)); - } - - LOG.debug("Deleting unassigned ACL: iid={} dataBefore={}", id, dataBefore); - - // no vpp call, just updates DataTree - } - - private static boolean isAssigned(@Nonnull final Acl acl, - @Nonnull final WriteContext writeContext) { - final String aclName = acl.getAclName(); - final Class aclType = acl.getAclType(); - final Interfaces interfaces = writeContext.readAfter(InstanceIdentifier.create(Interfaces.class)).get(); - - return interfaces.getInterface().stream() - .map(i -> Optional.ofNullable(i.getAugmentation(VppInterfaceAugmentation.class)) - .map(aug -> aug.getIetfAcl()) - .map(ietfAcl -> ietfAcl.getIngress()) - .map(ingress -> ingress.getAccessLists()) - .map(accessLists -> accessLists.getAcl()) - ) - .flatMap(iacl -> iacl.isPresent() - ? iacl.get().stream() - : Stream.empty()) - .filter(assignedAcl -> aclName.equals(assignedAcl.getName()) && aclType.equals(assignedAcl.getType())) - .findFirst().isPresent(); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AbstractIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AbstractIetfAclWriter.java deleted file mode 100644 index 347397aa3..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AbstractIetfAclWriter.java +++ /dev/null @@ -1,251 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntries; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.AceType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.AceIpVersion; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class AbstractIetfAclWriter implements IetfAclWriter, JvppReplyConsumer, AclTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(AbstractIetfAclWriter.class); - protected static final int NOT_DEFINED = -1; - protected final FutureJVppCore jvpp; - - private Map> aceWriters = new HashMap<>(); - - public AbstractIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore) { - this.jvpp = Preconditions.checkNotNull(futureJVppCore, "futureJVppCore should not be null"); - aceWriters.put(AclType.ETH, new AceEthWriter()); - aceWriters.put(AclType.IP4, new AceIp4Writer()); - aceWriters.put(AclType.IP6, new AceIp6Writer()); - aceWriters.put(AclType.ETH_AND_IP, new AceIpAndEthWriter()); - } - - private static Stream aclToAceStream(@Nonnull final Acl assignedAcl, - @Nonnull final WriteContext writeContext) { - final String aclName = assignedAcl.getName(); - final Class aclType = assignedAcl.getType(); - - // ietf-acl updates are handled first, so we use writeContext.readAfter - final Optional - aclOptional = - writeContext.readAfter(io.fd.honeycomb.translate.v3po.interfaces.acl.IetfAclWriter.ACL_ID.child( - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl.class, - new AclKey(aclName, aclType))); - checkArgument(aclOptional.isPresent(), "Acl lists not configured"); - final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl - acl = aclOptional.get(); - - final AccessListEntries accessListEntries = acl.getAccessListEntries(); - checkArgument(accessListEntries != null, "access list entries not configured"); - - return accessListEntries.getAce().stream(); - } - - protected void removeClassifyTables(@Nonnull final InstanceIdentifier id, @Nonnull final MappingEntry entry) - throws WriteFailedException { - removeClassifyTable(id, entry.getL2TableId()); - removeClassifyTable(id, entry.getIp4TableId()); - removeClassifyTable(id, entry.getIp6TableId()); - } - - private void removeClassifyTable(@Nonnull final InstanceIdentifier id, final int tableIndex) - throws WriteFailedException { - - if (tableIndex == -1) { - return; // classify table id is absent - } - final ClassifyAddDelTable request = new ClassifyAddDelTable(); - request.tableIndex = tableIndex; - final CompletionStage cs = jvpp.classifyAddDelTable(request); - getReplyForDelete(cs.toCompletableFuture(), id); - } - - protected static boolean appliesToIp4Path(final Ace ace) { - final AceType aceType = ace.getMatches().getAceType(); - final AclType aclType = AclType.fromAce(ace); - if (aclType == AclType.IP4) { - return true; - } - if (aclType == AclType.ETH) { - return true; // L2 only rules are possible for IP4 traffic - } - if (aclType == AclType.ETH_AND_IP && ((AceIpAndEth) aceType) - .getAceIpVersion() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv4) { - return true; - } - return false; - } - - protected static boolean appliesToIp6Path(final Ace ace) { - final AceType aceType = ace.getMatches().getAceType(); - final AclType aclType = AclType.fromAce(ace); - if (aclType == AclType.IP6) { - return true; - } - if (aclType == AclType.ETH) { - return true; // L2 only rules are possible for IP6 traffic - } - if (aclType == AclType.ETH_AND_IP && ((AceIpAndEth) aceType) - .getAceIpVersion() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv6) { - return true; - } - return false; - } - - protected static List getACEs(@Nonnull final List acls, @Nonnull final WriteContext writeContext, - final Predicate filter) { - return acls.stream().flatMap(acl -> aclToAceStream(acl, writeContext)).filter(filter) - .collect(Collectors.toList()); - } - - protected int writeAces(final InstanceIdentifier id, final List aces, - final AccessLists.DefaultAction defaultAction, final InterfaceMode mode, - final int vlanTags) throws WriteFailedException { - if (aces.isEmpty()) { - return NOT_DEFINED; - } - - int nextTableIndex = configureDefaultAction(id, defaultAction); - final ListIterator iterator = aces.listIterator(aces.size()); - while (iterator.hasPrevious()) { - final Ace ace = iterator.previous(); - LOG.trace("Processing ACE: {}", ace); - - final AceWriter aceWriter = - aceWriters.get(AclType.fromAce(ace)); - if (aceWriter == null) { - LOG.warn("AceProcessor for {} not registered. Skipping ACE.", ace.getClass()); - } else { - final AceType aceType = ace.getMatches().getAceType(); - final PacketHandling action = ace.getActions().getPacketHandling(); - final ClassifyAddDelTable ctRequest = aceWriter.createTable(aceType, mode, nextTableIndex, vlanTags); - nextTableIndex = createClassifyTable(id, ctRequest); - final List sessionRequests = - aceWriter.createSession(action, aceType, mode, nextTableIndex, vlanTags); - for (ClassifyAddDelSession csRequest : sessionRequests) { - createClassifySession(id, csRequest); - } - } - } - return nextTableIndex; - } - - private int configureDefaultAction(@Nonnull final InstanceIdentifier id, - final AccessLists.DefaultAction defaultAction) - throws WriteFailedException { - ClassifyAddDelTable ctRequest = createTable(-1); - if (AccessLists.DefaultAction.Permit.equals(defaultAction)) { - ctRequest.missNextIndex = -1; - } else { - ctRequest.missNextIndex = 0; - } - ctRequest.mask = new byte[16]; - ctRequest.skipNVectors = 0; - ctRequest.matchNVectors = 1; - return createClassifyTable(id, ctRequest); - } - - private int createClassifyTable(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyAddDelTable request) - throws WriteFailedException { - final CompletionStage cs = jvpp.classifyAddDelTable(request); - - final ClassifyAddDelTableReply reply = getReplyForWrite(cs.toCompletableFuture(), id); - return reply.newTableIndex; - } - - private void createClassifySession(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyAddDelSession request) - throws WriteFailedException { - final CompletionStage cs = jvpp.classifyAddDelSession(request); - - getReplyForWrite(cs.toCompletableFuture(), id); - } - - private enum AclType { - ETH, IP4, IP6, ETH_AND_IP; - - @Nonnull - private static AclType fromAce(final Ace ace) { - AclType result = null; - final AceType aceType; - try { - aceType = ace.getMatches().getAceType(); - if (aceType instanceof AceEth) { - result = ETH; - } else if (aceType instanceof AceIp) { - final AceIpVersion aceIpVersion = ((AceIp) aceType).getAceIpVersion(); - if (aceIpVersion == null) { - throw new IllegalArgumentException("Incomplete ACE (ip-version was not provided): " + ace); - } - if (aceIpVersion instanceof AceIpv4) { - result = IP4; - } else if (aceIpVersion instanceof AceIpv6) { - result = IP6; - } - } else if (aceType instanceof AceIpAndEth) { - result = ETH_AND_IP; - } - } catch (NullPointerException e) { - throw new IllegalArgumentException("Incomplete ACE: " + ace, e); - } - if (result == null) { - throw new IllegalArgumentException(String.format("Not supported ace type %s", aceType)); - } - return result; - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceEthWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceEthWriter.java deleted file mode 100644 index 14124dcc7..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceEthWriter.java +++ /dev/null @@ -1,85 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import com.google.common.annotations.VisibleForTesting; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class AceEthWriter implements AceWriter, AclTranslator, L2AclTranslator { - - @VisibleForTesting - static final int MATCH_N_VECTORS = 1; - private static final Logger LOG = LoggerFactory.getLogger(AceEthWriter.class); - - @Override - public ClassifyAddDelTable createTable(@Nonnull final AceEth aceEth, - @Nullable final InterfaceMode mode, - final int nextTableIndex, - final int vlanTags) { - final ClassifyAddDelTable request = createTable(nextTableIndex); - - request.mask = new byte[16]; - boolean aceIsEmpty = - destinationMacAddressMask(aceEth.getDestinationMacAddressMask(), aceEth.getDestinationMacAddress(), - request); - aceIsEmpty &= - sourceMacAddressMask(aceEth.getSourceMacAddressMask(), aceEth.getSourceMacAddress(), request); - - if (aceIsEmpty) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceEth.toString())); - } - - request.skipNVectors = 0; - request.matchNVectors = MATCH_N_VECTORS; - - LOG.debug("ACE rule={} translated to table={}.", aceEth, request); - return request; - } - - @Override - public List createSession(@Nonnull final PacketHandling action, - @Nonnull final AceEth aceEth, - @Nullable final InterfaceMode mode, - final int tableIndex, - final int vlanTags) { - final ClassifyAddDelSession request = createSession(action, tableIndex); - - request.match = new byte[16]; - boolean noMatch = destinationMacAddressMatch(aceEth.getDestinationMacAddress(), request); - noMatch &= sourceMacAddressMatch(aceEth.getSourceMacAddress(), request); - - if (noMatch) { - throw new IllegalArgumentException( - String.format("Ace %s does not define neither source nor destination MAC address", - aceEth.toString())); - } - - LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceEth, request); - return Collections.singletonList(request); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp4Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp4Writer.java deleted file mode 100644 index 7d75e3969..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp4Writer.java +++ /dev/null @@ -1,94 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.annotations.VisibleForTesting; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class AceIp4Writer implements AceWriter, AclTranslator, Ip4AclTranslator { - - @VisibleForTesting - static final int MATCH_N_VECTORS = 3; // number of 16B vectors - private static final int TABLE_MASK_LENGTH = 48; - private static final Logger LOG = LoggerFactory.getLogger(AceIp4Writer.class); - - @Override - public ClassifyAddDelTable createTable(@Nonnull final AceIp aceIp, - @Nullable final InterfaceMode mode, - final int nextTableIndex, - final int vlanTags) { - checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp); - final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion(); - - final int numberOfSessions = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()).size(); - final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); - request.skipNVectors = 0; // match entire L2 and L3 header - request.matchNVectors = MATCH_N_VECTORS; - request.mask = new byte[TABLE_MASK_LENGTH]; - - final int baseOffset = getVlanTagsLen(vlanTags); - boolean aceIsEmpty = ip4Mask(baseOffset, mode, aceIp, ipVersion, request); - if (aceIsEmpty) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); - } - - LOG.debug("ACE rule={} translated to table={}.", aceIp, request); - return request; - } - - @Override - public List createSession(@Nonnull final PacketHandling action, - @Nonnull final AceIp aceIp, - @Nullable final InterfaceMode mode, - final int tableIndex, - final int vlanTags) { - checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp); - final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion(); - - final List portPairs = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()); - final List requests = new ArrayList<>(portPairs.size()); - for (final PortPair pair : portPairs) { - final ClassifyAddDelSession request = createSession(action, tableIndex); - request.match = new byte[TABLE_MASK_LENGTH]; - - final int baseOffset = getVlanTagsLen(vlanTags); - boolean noMatch = ip4Match(baseOffset, mode, aceIp, ipVersion, pair.getSrc(), pair.getDst(), request); - if (noMatch) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); - } - - LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request); - requests.add(request); - } - return requests; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp6Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp6Writer.java deleted file mode 100644 index cad80022e..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp6Writer.java +++ /dev/null @@ -1,99 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class AceIp6Writer implements AceWriter, AclTranslator, Ip6AclTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(AceIp6Writer.class); - - @Override - public ClassifyAddDelTable createTable(@Nonnull final AceIp aceIp, - @Nullable final InterfaceMode mode, - final int nextTableIndex, - final int vlanTags) { - checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp); - final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion(); - - final int numberOfSessions = PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()).size(); - final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); - request.skipNVectors = 0; // match entire L2 and L3 header - request.mask = new byte[getTableMaskLength(vlanTags)]; - request.matchNVectors = request.mask.length/16; - - final int baseOffset = getVlanTagsLen(vlanTags); - boolean aceIsEmpty = ip6Mask(baseOffset, mode, aceIp, ipVersion, request); - if (aceIsEmpty) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); - } - - LOG.debug("ACE rule={} translated to table={}.", aceIp, request); - return request; - } - - private static int getTableMaskLength(final int vlanTags) { - if (vlanTags == 2) { - return 80; - } else { - return 64; - } - } - - @Override - public List createSession(@Nonnull final PacketHandling action, - @Nonnull final AceIp aceIp, - @Nullable final InterfaceMode mode, - final int tableIndex, - final int vlanTags) { - checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp); - final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion(); - final List portPairs = - PortPair.fromRange(aceIp.getSourcePortRange(), aceIp.getDestinationPortRange()); - - final List requests = new ArrayList<>(portPairs.size()); - for (final PortPair pair : portPairs) { - final ClassifyAddDelSession request = createSession(action, tableIndex); - request.match = new byte[getTableMaskLength(vlanTags)]; - - final int baseOffset = getVlanTagsLen(vlanTags); - boolean noMatch = ip6Match(baseOffset, mode, aceIp, ipVersion, pair.getSrc(), pair.getDst(), request); - if (noMatch) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); - } - - LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request); - requests.add(request); - } - return requests; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpAndEthWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpAndEthWriter.java deleted file mode 100644 index ca12cbe19..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpAndEthWriter.java +++ /dev/null @@ -1,129 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.AceIpVersion; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv4; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv6; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class AceIpAndEthWriter - implements AceWriter, AclTranslator, L2AclTranslator, Ip4AclTranslator, Ip6AclTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(AceIpAndEthWriter.class); - - private static int maskLength(@Nonnull final AceIpAndEth ace, final int vlanTags) { - if (ace.getAceIpVersion() != null) { - if (ace.getAceIpVersion() instanceof AceIpv4) { - return 48; - } else { - return vlanTags == 2 - ? 80 - : 64; - } - } - return 16; - } - - @Override - public ClassifyAddDelTable createTable(@Nonnull final AceIpAndEth ace, @Nullable final InterfaceMode mode, - final int nextTableIndex, final int vlanTags) { - final int numberOfSessions = PortPair.fromRange(ace.getSourcePortRange(), ace.getDestinationPortRange()).size(); - final ClassifyAddDelTable request = createTable(nextTableIndex, numberOfSessions); - final int maskLength = maskLength(ace, vlanTags); - request.mask = new byte[maskLength]; - request.skipNVectors = 0; - request.matchNVectors = maskLength / 16; - - boolean aceIsEmpty = - destinationMacAddressMask(ace.getDestinationMacAddressMask(), ace.getDestinationMacAddress(), request); - aceIsEmpty &= sourceMacAddressMask(ace.getSourceMacAddressMask(), ace.getSourceMacAddress(), request); - - // if we use classifier API, we need to know ip version (fields common for ip4 and ip6 have different offsets): - final AceIpVersion aceIpVersion = ace.getAceIpVersion(); - checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion"); - - final int baseOffset = getVlanTagsLen(vlanTags); - if (aceIpVersion instanceof AceIpv4) { - final AceIpv4 ipVersion = (AceIpv4) aceIpVersion; - aceIsEmpty &= ip4Mask(baseOffset, mode, ace, ipVersion, request); - } else if (aceIpVersion instanceof AceIpv6) { - final AceIpv6 ipVersion = (AceIpv6) aceIpVersion; - aceIsEmpty &= ip6Mask(baseOffset, mode, ace, ipVersion, request); - } else { - throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion)); - } - - if (aceIsEmpty) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", ace.toString())); - } - - LOG.debug("ACE rule={} translated to table={}.", ace, request); - return request; - } - - @Override - public List createSession(@Nonnull final PacketHandling action, - @Nonnull final AceIpAndEth ace, - @Nullable final InterfaceMode mode, final int tableIndex, - final int vlanTags) { - final List portPairs = PortPair.fromRange(ace.getSourcePortRange(), ace.getDestinationPortRange()); - final List requests = new ArrayList<>(portPairs.size()); - for (final PortPair pair : portPairs) { - final ClassifyAddDelSession request = createSession(action, tableIndex); - request.match = new byte[maskLength(ace, vlanTags)]; - - boolean noMatch = destinationMacAddressMatch(ace.getDestinationMacAddress(), request); - noMatch &= sourceMacAddressMatch(ace.getSourceMacAddress(), request); - - final AceIpVersion aceIpVersion = ace.getAceIpVersion(); - checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion"); - - final int baseOffset = getVlanTagsLen(vlanTags); - if (aceIpVersion instanceof AceIpv4) { - final AceIpv4 ipVersion = (AceIpv4) aceIpVersion; - noMatch &= ip4Match(baseOffset, mode, ace, ipVersion, pair.getSrc(), pair.getDst(), request); - } else if (aceIpVersion instanceof AceIpv6) { - final AceIpv6 ipVersion = (AceIpv6) aceIpVersion; - noMatch &= ip6Match(baseOffset, mode, ace, ipVersion, pair.getSrc(), pair.getDst(), request); - } else { - throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion)); - } - - if (noMatch) { - throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", ace.toString())); - } - LOG.debug("ACE action={}, rule={} translated to session={}.", action, ace, request); - requests.add(request); - } - return requests; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceWriter.java deleted file mode 100644 index ae540f94d..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceWriter.java +++ /dev/null @@ -1,54 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.AceType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; - -/** - * Writer responsible for translation of ietf-acl model ACEs to VPP's classify tables and sessions. - * - * @param type of access control list entry - */ -interface AceWriter { - /** - * @param ace access list entry - * @param mode interface mode (L2/L3) - * @param nextTableIndex index of the next classify table in chain - * @param vlanTags number of vlan tags - */ - @Nonnull - ClassifyAddDelTable createTable(@Nonnull final T ace, @Nullable final InterfaceMode mode, final int nextTableIndex, - final int vlanTags); - - /** - * @param action to be taken when packet does match the specified ace - * @param ace access list entry - * @param mode interface mode (L2/L3) - * @param tableIndex index of corresponding classify table - * @param vlanTags number of vlan tags - */ - @Nonnull - List createSession(@Nonnull final PacketHandling action, @Nonnull T ace, - @Nullable final InterfaceMode mode, final int tableIndex, final int vlanTags); -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManager.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManager.java deleted file mode 100644 index bddc16a23..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManager.java +++ /dev/null @@ -1,53 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; - -/** - * Manages interface metadata for ietf-acl model. - */ -public interface AclTableContextManager { - - /** - * Obtains mapping entry for given interface. - * - * @param index interface index - * @param mappingContext mapping context providing context data for current transaction - * @return ietf-acl metadata for given interface - */ - Optional getEntry(final int index, @Nonnull final MappingContext mappingContext); - - /** - * Adds mapping entry. - * - * @param entry to be added - * @param mappingContext mapping context providing context data for current transaction - */ - void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext); - - /** - * Removes entry for given interface (if present). - * - * @param index interface index - * @param mappingContext mapping context providing context data for current transaction - */ - void removeEntry(final int index, @Nonnull final MappingContext mappingContext); -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImpl.java deleted file mode 100644 index 60fb0d24b..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImpl.java +++ /dev/null @@ -1,68 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import javax.annotation.Nonnull; -import javax.annotation.concurrent.ThreadSafe; -import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.AclMappingEntryCtxAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.AclMappingEntryContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTableKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -@ThreadSafe -public class AclTableContextManagerImpl implements AclTableContextManager { - - private MappingTable.Direction direction; - - public AclTableContextManagerImpl(@Nonnull final MappingTable.Direction direction) { - this.direction = checkNotNull(direction, "direction should not be null"); - } - - @Nonnull - @Override - public synchronized Optional getEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { - return mappingContext.read(getId(swIfIndex)); - } - - @Override - public synchronized void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext) { - mappingContext.put(getId(entry.getIndex()), entry); - } - - @Override - public synchronized void removeEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { - mappingContext.delete(getId(swIfIndex)); - } - - @VisibleForTesting - protected InstanceIdentifier getId(final int index) { - return InstanceIdentifier.create(Contexts.class) - .augmentation(AclMappingEntryCtxAugmentation.class) - .child(AclMappingEntryContext.class) - .child(MappingTable.class, new MappingTableKey(direction)) - .child(MappingEntry.class, new MappingEntryKey(index)); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTranslator.java deleted file mode 100644 index 2d898f1d9..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTranslator.java +++ /dev/null @@ -1,74 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit; - -/** - * Utility that helps translating of ietf-acl model ACEs to VPP's classify tables and sessions. - */ -interface AclTranslator { - int TABLE_MEM_SIZE = 8 * 1024; - int VLAN_TAG_LEN = 4; - - default ClassifyAddDelTable createTable(final int nextTableIndex) { - return createTable(nextTableIndex, 1); - } - - default ClassifyAddDelTable createTable(final int nextTableIndex, @Nonnegative final int numberOfSessions) { - final ClassifyAddDelTable request = new ClassifyAddDelTable(); - request.isAdd = 1; - request.tableIndex = -1; // value not present - request.nbuckets = numberOfSessions; - request.nextTableIndex = nextTableIndex; - - - // TODO: HONEYCOMB-181 minimise memory used by classify tables (we create a lot of them to make ietf-acl model - // mapping more convenient): - // according to https://wiki.fd.io/view/VPP/Introduction_To_N-tuple_Classifiers#Creating_a_classifier_table, - // classify table needs 16*(1 + match_n_vectors) bytes, but this does not quite work, - // so setting 8K +1k*numberOfSessions for now - checkArgument(numberOfSessions>0, "negative numberOfSessions %s", numberOfSessions); - request.memorySize = TABLE_MEM_SIZE+1024*(numberOfSessions-1); - request.missNextIndex = -1; // value not set, but anyway it is ignored for tables in chain - return request; - } - - default ClassifyAddDelSession createSession(@Nonnull final PacketHandling action, final int tableIndex) { - final ClassifyAddDelSession request = new ClassifyAddDelSession(); - request.isAdd = 1; - request.tableIndex = tableIndex; - request.opaqueIndex = ~0; // value not used - - if (action instanceof Permit) { - request.hitNextIndex = -1; - } // deny (0) is default value - - return request; - } - - default int getVlanTagsLen(final int vlanTags) { - return vlanTags * VLAN_TAG_LEN; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/IetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/IetfAclWriter.java deleted file mode 100644 index 2e8750cd5..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/IetfAclWriter.java +++ /dev/null @@ -1,47 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.List; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public interface IetfAclWriter { - default void write(@Nonnull final InstanceIdentifier id, final int ifIndex, @Nonnull final List acls, - final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - write(id, ifIndex, acls, defaultAction, mode, writeContext, 0, mappingContext); - } - - void write(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final List acls, - final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException; - - void deleteAcl(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final MappingContext mappingContext) - throws WriteFailedException; -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/Ip4AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/Ip4AclTranslator.java deleted file mode 100644 index 304d6c1f0..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/Ip4AclTranslator.java +++ /dev/null @@ -1,149 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import com.google.common.primitives.Ints; -import io.fd.honeycomb.translate.vpp.util.Ipv4Translator; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpHeaderFields; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv4HeaderFields; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; - -interface Ip4AclTranslator extends Ipv4Translator { - int ETHER_TYPE_OFFSET = 12; // first 14 bytes represent L2 header (2x6) - int DSCP_OFFSET = 15; - int DSCP_MASK = 0xfc; - - int IP_PROTOCOL_OFFSET = ETHER_TYPE_OFFSET + 11; - int IP_PROTOCOL_MASK = 0xff; - - int IP4_LEN = 4; - int IP4_MASK_BIT_LENGTH = 32; - int SRC_IP_OFFSET = ETHER_TYPE_OFFSET + 14; - int DST_IP_OFFSET = SRC_IP_OFFSET + IP4_LEN; - int SRC_PORT_OFFSET = DST_IP_OFFSET + IP4_LEN; - int DST_PORT_OFFSET = SRC_PORT_OFFSET + 2; - - default boolean ip4Mask(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, - final AclIpv4HeaderFields ip4, final ClassifyAddDelTable request) { - boolean aceIsEmpty = true; - if (InterfaceMode.L2.equals(mode)) { - // in L2 mode we need to match ether type - request.mask[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0xff; - request.mask[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xff; - } - if (header.getDscp() != null) { - aceIsEmpty = false; - request.mask[baseOffset + DSCP_OFFSET] = (byte) DSCP_MASK; // first 6 bits - } - if (header.getProtocol() != null) { // Internet Protocol number - aceIsEmpty = false; - request.mask[baseOffset + IP_PROTOCOL_OFFSET] = (byte) IP_PROTOCOL_MASK; - } - if (header.getSourcePortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - aceIsEmpty = false; - request.mask[baseOffset + SRC_PORT_OFFSET] = (byte) 0xff; - request.mask[baseOffset + SRC_PORT_OFFSET + 1] = (byte) 0xff; - } - if (header.getDestinationPortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - aceIsEmpty = false; - request.mask[baseOffset + DST_PORT_OFFSET] = (byte) 0xff; - request.mask[baseOffset + DST_PORT_OFFSET + 1] = (byte) 0xff; - } - if (ip4.getSourceIpv4Network() != null) { - aceIsEmpty = false; - System.arraycopy(Impl.toByteMask(ip4.getSourceIpv4Network()), 0, request.mask, - baseOffset + SRC_IP_OFFSET, IP4_LEN); - } - if (ip4.getDestinationIpv4Network() != null) { - aceIsEmpty = false; - System.arraycopy(Impl.toByteMask(ip4.getDestinationIpv4Network()), 0, request.mask, - baseOffset + DST_IP_OFFSET, IP4_LEN); - } - return aceIsEmpty; - } - - default boolean ip4Match(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, - final AclIpv4HeaderFields ip4, final Integer srcPort, - final Integer dstPort, final ClassifyAddDelSession request) { - boolean noMatch = true; - if (InterfaceMode.L2.equals(mode)) { - // match IP4 etherType (0x0800) - request.match[baseOffset + ETHER_TYPE_OFFSET] = 0x08; - request.match[baseOffset + ETHER_TYPE_OFFSET + 1] = 0x00; - } - if (header.getDscp() != null) { - noMatch = false; - request.match[baseOffset + DSCP_OFFSET] = (byte) (DSCP_MASK & (header.getDscp().getValue() << 2)); - } - if (header.getProtocol() != null) { // Internet Protocol number - noMatch = false; - request.match[baseOffset + IP_PROTOCOL_OFFSET] = (byte) (IP_PROTOCOL_MASK & header.getProtocol()); - } - if (srcPort != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - noMatch = false; - request.match[baseOffset + SRC_PORT_OFFSET] = (byte) (0xff & srcPort >> 8); - request.match[baseOffset + SRC_PORT_OFFSET + 1] = (byte) (0xff & srcPort); - } - if (header.getDestinationPortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - noMatch = false; - request.match[baseOffset + DST_PORT_OFFSET] = (byte) (0xff & dstPort >> 8); - request.match[baseOffset + DST_PORT_OFFSET + 1] = (byte) (0xff & dstPort); - } - if (ip4.getSourceIpv4Network() != null) { - noMatch = false; - System.arraycopy(Impl.toMatchValue(ip4.getSourceIpv4Network()), 0, request.match, - baseOffset + SRC_IP_OFFSET, IP4_LEN); - - } - if (ip4.getDestinationIpv4Network() != null) { - noMatch = false; - System.arraycopy(Impl.toMatchValue(ip4.getDestinationIpv4Network()), 0, request.match, - baseOffset + DST_IP_OFFSET, IP4_LEN); - - } - return noMatch; - } - - class Impl { - private static byte[] toByteMask(final int prefixLength) { - final long mask = ((1L << prefixLength) - 1) << (IP4_MASK_BIT_LENGTH - prefixLength); - return Ints.toByteArray((int) mask); - } - - private static byte[] toByteMask(final Ipv4Prefix ipv4Prefix) { - final int prefixLength = Byte.valueOf(ipv4Prefix.getValue().split("/")[1]); - return toByteMask(prefixLength); - } - - private static byte[] toMatchValue(final Ipv4Prefix ipv4Prefix) { - final String[] split = ipv4Prefix.getValue().split("/"); - final byte[] addressBytes = Ipv4Translator.INSTANCE.ipv4AddressNoZoneToArray(split[0]); - final byte[] mask = Impl.toByteMask(Byte.valueOf(split[1])); - for (int i = 0; i < addressBytes.length; ++i) { - addressBytes[i] &= mask[i]; - } - return addressBytes; - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/Ip6AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/Ip6AclTranslator.java deleted file mode 100644 index c0da75687..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/Ip6AclTranslator.java +++ /dev/null @@ -1,182 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.BitSet; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpHeaderFields; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv6HeaderFields; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; - -interface Ip6AclTranslator { - - int ETHER_TYPE_OFFSET = 12; // first 14 bytes represent L2 header (2x6) - int IP_VERSION_OFFSET = ETHER_TYPE_OFFSET + 2; - int DSCP_MASK1 = 0x0f; - int DSCP_MASK2 = 0xc0; - int IP_PROTOCOL_OFFSET = IP_VERSION_OFFSET + 6; - int IP_PROTOCOL_MASK = 0xff; - int IP6_LEN = 16; - int SRC_IP_OFFSET = IP_VERSION_OFFSET + 8; - int DST_IP_OFFSET = SRC_IP_OFFSET + IP6_LEN; - int SRC_PORT_OFFSET = DST_IP_OFFSET + IP6_LEN; - int DST_PORT_OFFSET = SRC_PORT_OFFSET + 2; - - default boolean ip6Mask(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, - final AclIpv6HeaderFields ip6, final ClassifyAddDelTable request) { - boolean aceIsEmpty = true; - if (InterfaceMode.L2.equals(mode)) { - // in L2 mode we need to match ether type - request.mask[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0xff; - request.mask[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xff; - } - if (header.getDscp() != null) { - aceIsEmpty = false; - // DCSP (bits 4-9 of IP6 header) - request.mask[baseOffset + IP_VERSION_OFFSET] |= DSCP_MASK1; - request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= DSCP_MASK2; - } - if (header.getProtocol() != null) { // Internet Protocol number - aceIsEmpty = false; - request.mask[baseOffset + IP_PROTOCOL_OFFSET] = (byte) IP_PROTOCOL_MASK; - } - if (ip6.getFlowLabel() != null) { - aceIsEmpty = false; - // bits 12-31 - request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) 0x0f; - request.mask[baseOffset + IP_VERSION_OFFSET + 2] = (byte) 0xff; - request.mask[baseOffset + IP_VERSION_OFFSET + 3] = (byte) 0xff; - } - if (header.getSourcePortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - aceIsEmpty = false; - request.mask[baseOffset + SRC_PORT_OFFSET] = (byte) 0xff; - request.mask[baseOffset + SRC_PORT_OFFSET + 1] = (byte) 0xff; - } - if (header.getDestinationPortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - aceIsEmpty = false; - request.mask[baseOffset + DST_PORT_OFFSET] = (byte) 0xff; - request.mask[baseOffset + DST_PORT_OFFSET + 1] = (byte) 0xff; - } - if (ip6.getSourceIpv6Network() != null) { - aceIsEmpty = false; - final byte[] mask = Impl.toByteMask(ip6.getSourceIpv6Network()); - System.arraycopy(mask, 0, request.mask, baseOffset + SRC_IP_OFFSET, mask.length); - } - if (ip6.getDestinationIpv6Network() != null) { - aceIsEmpty = false; - final byte[] mask = Impl.toByteMask(ip6.getDestinationIpv6Network()); - System.arraycopy(mask, 0, request.mask, baseOffset + DST_IP_OFFSET, mask.length); - } - return aceIsEmpty; - } - - default boolean ip6Match(final int baseOffset, final InterfaceMode mode, final AclIpHeaderFields header, - final AclIpv6HeaderFields ip6, final Integer srcPort, final Integer dstPort, final ClassifyAddDelSession request) { - boolean noMatch = true; - if (InterfaceMode.L2.equals(mode)) { - // match IP6 etherType (0x86dd) - request.match[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0x86; - request.match[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xdd; - } - if (header.getDscp() != null) { - noMatch = false; - final int dcsp = header.getDscp().getValue(); - // set bits 4-9 of IP6 header: - request.match[baseOffset + IP_VERSION_OFFSET] |= (byte) (DSCP_MASK1 & (dcsp >> 2)); - request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (DSCP_MASK2 & (dcsp << 6)); - } - if (header.getProtocol() != null) { // Internet Protocol number - noMatch = false; - request.match[baseOffset + IP_PROTOCOL_OFFSET] = (byte) (IP_PROTOCOL_MASK & header.getProtocol()); - } - if (ip6.getFlowLabel() != null) { - noMatch = false; - final int flowLabel = ip6.getFlowLabel().getValue().intValue(); - // bits 12-31 - request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (0x0f & (flowLabel >> 16)); - request.match[baseOffset + IP_VERSION_OFFSET + 2] = (byte) (0xff & (flowLabel >> 8)); - request.match[baseOffset + IP_VERSION_OFFSET + 3] = (byte) (0xff & flowLabel); - } - if (header.getSourcePortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - noMatch = false; - request.match[baseOffset + SRC_PORT_OFFSET] = (byte) (0xff & srcPort >> 8); - request.match[baseOffset + SRC_PORT_OFFSET + 1] = (byte) (0xff & srcPort); - } - if (header.getDestinationPortRange() != null) { - // TODO (HONEYCOMB-253): port matching will not work correctly if Options are present - noMatch = false; - request.match[baseOffset + DST_PORT_OFFSET] = (byte) (0xff & dstPort >> 8); - request.match[baseOffset + DST_PORT_OFFSET + 1] = (byte) (0xff & dstPort); - } - if (ip6.getSourceIpv6Network() != null) { - noMatch = false; - final byte[] match = Impl.toMatchValue(ip6.getSourceIpv6Network()); - System.arraycopy(match, 0, request.match, baseOffset + SRC_IP_OFFSET, IP6_LEN); - } - if (ip6.getDestinationIpv6Network() != null) { - noMatch = false; - final byte[] match = Impl.toMatchValue(ip6.getDestinationIpv6Network()); - System.arraycopy(match, 0, request.match, baseOffset + DST_IP_OFFSET, IP6_LEN); - } - return noMatch; - } - - class Impl { - private static final int IP6_MASK_BIT_LENGTH = 128; - - private static byte[] toByteMask(final int prefixLength) { - final BitSet mask = new BitSet(IP6_MASK_BIT_LENGTH); - mask.set(0, prefixLength, true); - if (prefixLength < IP6_MASK_BIT_LENGTH) { - mask.set(prefixLength, IP6_MASK_BIT_LENGTH, false); - } - return mask.toByteArray(); - } - - private static byte[] toByteMask(final Ipv6Prefix ipv6Prefix) { - final int prefixLength = Short.valueOf(ipv6Prefix.getValue().split("/")[1]); - return toByteMask(prefixLength); - } - - private static byte[] toMatchValue(final Ipv6Prefix ipv6Prefix) { - final String[] split = ipv6Prefix.getValue().split("/"); - final byte[] addressBytes; - try { - addressBytes = InetAddress.getByName(split[0]).getAddress(); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Invalid IP6 address", e); - } - final byte[] mask = toByteMask(Short.valueOf(split[1])); - int pos = 0; - for (; pos < mask.length; ++pos) { - addressBytes[pos] &= mask[pos]; - } - // mask can be shorter that address, so we need to clear rest of the address: - for (; pos < addressBytes.length; ++pos) { - addressBytes[pos] = 0; - } - return addressBytes; - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/L2AclTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/L2AclTranslator.java deleted file mode 100644 index c74db7e2a..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/L2AclTranslator.java +++ /dev/null @@ -1,90 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import io.fd.honeycomb.translate.vpp.util.MacTranslator; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import java.util.List; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; - -interface L2AclTranslator extends MacTranslator { - - default boolean destinationMacAddressMask(final MacAddress dstMask, final MacAddress dstAddress, - final ClassifyAddDelTable request) { - // destination-mac-address or destination-mac-address-mask is present => - // ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00:00:00 - if (dstMask != null) { - final List parts = COLON_SPLITTER.splitToList(dstMask.getValue()); - int i = 0; - for (String part : parts) { - request.mask[i++] = parseHexByte(part); - } - return false; - } else if (dstAddress != null) { - for (int i = 0; i < 6; ++i) { - request.mask[i] = (byte) 0xff; - } - return false; - } - return true; - } - - default boolean sourceMacAddressMask(final MacAddress srcMask, final MacAddress srcAddress, - final ClassifyAddDelTable request) { - // source-mac-address or source-mac-address-mask => - // 00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:00:00:00:00 - if (srcMask != null) { - final List parts = COLON_SPLITTER.splitToList(srcMask.getValue()); - int i = 6; - for (String part : parts) { - request.mask[i++] = parseHexByte(part); - } - return false; - } else if (srcAddress != null) { - for (int i = 6; i < 12; ++i) { - request.mask[i] = (byte) 0xff; - } - return false; - } - return true; - } - - default boolean destinationMacAddressMatch(final MacAddress dstAddress, final ClassifyAddDelSession request) { - if (dstAddress != null) { - final List parts = COLON_SPLITTER.splitToList(dstAddress.getValue()); - int i = 0; - for (String part : parts) { - request.match[i++] = parseHexByte(part); - } - return false; - } - return true; - } - - default boolean sourceMacAddressMatch(final MacAddress srcAddress, final ClassifyAddDelSession request) { - if (srcAddress != null) { - final List parts = COLON_SPLITTER.splitToList(srcAddress.getValue()); - int i = 6; - for (String part : parts) { - request.match[i++] = parseHexByte(part); - } - return false; - } - return true; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/PortPair.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/PortPair.java deleted file mode 100644 index 6d5d506d8..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/PortPair.java +++ /dev/null @@ -1,126 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.BiFunction; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange; - -/** - * Utility that produces cartesian product out of src and dst port ranges (used to translate ranges into - * list of classify sessions). - */ -final class PortPair { - private final Integer src; - private final Integer dst; - - PortPair(@Nullable final Integer src, @Nullable final Integer dst) { - this.src = src; - this.dst = dst; - } - - Integer getSrc() { - return src; - } - - Integer getDst() { - return dst; - } - - @Override - public String toString() { - return "(" + src + "," + dst + ")"; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - final PortPair that = (PortPair) o; - if (!Objects.equals(src, that.src)) { - return false; - } - if (!Objects.equals(dst, that.dst)) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return Objects.hash(src, dst); - } - - static List fromRange(final SourcePortRange srcRange, - final DestinationPortRange dstRange) { - final List result = new ArrayList<>(); - if (srcRange == null && dstRange == null) { - result.add(new PortPair(null, null)); - } else if (srcRange != null && dstRange == null) { - processSingleRange(result, srcRange.getLowerPort(), srcRange.getUpperPort(), PortPair::new); - } else if (srcRange == null && dstRange != null) { - processSingleRange(result, dstRange.getLowerPort(), dstRange.getUpperPort(), - (dst, src) -> new PortPair(src, dst)); - } else { - processDoubleRange(result, srcRange, dstRange); - } - return result; - } - - private static void processSingleRange(final List result, - final PortNumber lowerPort, - final PortNumber upperPort, - final BiFunction f) { - int low = lowerPort.getValue(); // mandatory - int hi = low; - if (upperPort != null) { - hi = upperPort.getValue(); - } - for (; low <= hi; ++low) { - result.add(f.apply(low, null)); - } - } - - private static void processDoubleRange(final List result, final SourcePortRange srcRange, - final DestinationPortRange dstRange) { - int srcL = srcRange.getLowerPort().getValue(); - int srcH = srcL; - if (srcRange.getUpperPort() != null) { - srcH = srcRange.getUpperPort().getValue(); - } - int dstL = dstRange.getLowerPort().getValue(); - int dstH = dstL; - if (dstRange.getUpperPort() != null) { - dstH = dstRange.getUpperPort().getValue(); - } - for (int i=srcL; i <= srcH; ++i) { - for (int j=dstL; j <= dstH; ++j) { - result.add(new PortPair(i, j)); - } - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriter.java deleted file mode 100644 index bfd58cf4a..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriter.java +++ /dev/null @@ -1,120 +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.honeycomb.translate.v3po.interfaces.acl.egress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AbstractIetfAclWriter; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManager; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2Tables; -import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2TablesReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.List; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Matches; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class EgressIetfAclWriter extends AbstractIetfAclWriter { - private final AclTableContextManager aclCtx; - - public EgressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { - super(futureJVppCore); - this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); - } - - @Override - public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); - checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); - final MappingEntry entry = optional.get(); - unassignClassifyTables(id, swIfIndex); - removeClassifyTables(id, entry); - aclCtx.removeEntry(swIfIndex, mappingContext); - } - - private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, final int swIfIndex) - throws WriteFailedException { - final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); - request.swIfIndex = swIfIndex; - request.ip4TableIndex = NOT_DEFINED; - request.ip6TableIndex = NOT_DEFINED; - request.otherTableIndex = NOT_DEFINED; - request.isInput = 0; // egress - final CompletionStage cs = jvpp.classifySetInterfaceL2Tables(request); - getReplyForDelete(cs.toCompletableFuture(), id); - } - - @Override - public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, - @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); - checkArgument(InterfaceMode.L2.equals(mode), "Writing egress Acls is supported only in L2 mode"); - - final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); - request.isInput = 0; // egress - request.swIfIndex = swIfIndex; - - // applied to packets according to their ether type - final List ip4Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp4Path)); - request.ip4TableIndex = writeAces(id, ip4Aces, defaultAction, mode, numberOfTags); - final List ip6Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp6Path)); - request.ip6TableIndex = writeAces(id, ip6Aces, defaultAction, mode, numberOfTags); - final List aces = getACEs(acls, writeContext, EgressIetfAclWriter::isNotIpRule); - request.otherTableIndex = writeAces(id, aces, defaultAction, mode, numberOfTags); - - final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) - .setIp4TableId(request.ip4TableIndex) - .setIp6TableId(request.ip6TableIndex) - .setL2TableId(request.otherTableIndex) - .build(); - aclCtx.addEntry(entry, mappingContext); - - try { - getReplyForWrite(jvpp.classifySetInterfaceL2Tables(request).toCompletableFuture(), id); - } catch (WriteFailedException e) { - removeClassifyTables(id, entry); - throw e; - } - } - - private static boolean isNotIpRule(final Ace ace) { - final Matches matches = ace.getMatches(); - checkArgument(matches != null, "Incomplete ACE: %s", ace); - return matches.getAceType() instanceof AceEth; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizer.java deleted file mode 100644 index c0e4c3d14..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizer.java +++ /dev/null @@ -1,85 +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.honeycomb.translate.v3po.interfaces.acl.egress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.IetfAclWriter; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.v3po.rev161214.interfaces._interface.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class IetfAclCustomizer implements WriterCustomizer { - private static final Logger LOG = LoggerFactory.getLogger(IetfAclCustomizer.class); - private final IetfAclWriter aclWriter; - private final NamingContext interfaceContext; - - public IetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { - this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - LOG.debug("Adding egress ACLs for interface={}(id={}): {}", ifName, ifIndex, dataAfter); - - final AccessLists accessLists = dataAfter.getAccessLists(); - checkArgument(accessLists != null && accessLists.getAcl() != null, - "ietf-acl container does not define acl list"); - - if (!InterfaceMode.L2.equals(accessLists.getMode())) { - LOG.debug("Writing egress Acls is supported only in L2 mode. Ignoring config: {}", dataAfter); - return; - } - - aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, writeContext.getMappingContext()); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, - @Nonnull final Egress dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("ACLs update: removing previously configured ACLs"); - deleteCurrentAttributes(id, dataBefore, writeContext); - LOG.debug("ACLs update: adding updated ACLs"); - writeCurrentAttributes(id, dataAfter, writeContext); - LOG.debug("ACLs update was successful"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); - aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java deleted file mode 100644 index bf7c0eb46..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java +++ /dev/null @@ -1,105 +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.honeycomb.translate.v3po.interfaces.acl.egress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils.getNumberOfTags; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.IetfAclWriter; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIetfAclCustomizer.class); - private final IetfAclWriter aclWriter; - private final NamingContext interfaceContext; - - public SubInterfaceIetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { - this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - return SubInterfaceUtils - .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - LOG.debug("Adding IETF-ACL for sub-interface: {}(id={}): {}", subInterfaceName, subInterfaceIndex, dataAfter); - - final AccessLists accessLists = dataAfter.getAccessLists(); - checkArgument(accessLists != null && accessLists.getAcl() != null, - "ietf-acl container does not define acl list"); - - final Optional subInterfaceOptional = - writeContext.readAfter(id.firstIdentifierOf(SubInterface.class)); - checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id); - final SubInterface subInterface = subInterfaceOptional.get(); - - if (!InterfaceMode.L2.equals(accessLists.getMode())) { - LOG.debug("Writing egress Acls is supported only in L2 mode. Ignoring config: {}", dataAfter); - return; - } - - aclWriter - .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, - @Nonnull final Egress dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Sub-interface ACLs update: removing previously configured ACLs"); - deleteCurrentAttributes(id, dataBefore, writeContext); - LOG.debug("Sub-interface ACLs update: adding updated ACLs"); - writeCurrentAttributes(id, dataAfter, writeContext); - LOG.debug("Sub-interface ACLs update was successful"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Egress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); - aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AclCustomizer.java deleted file mode 100644 index 550c2cc92..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AclCustomizer.java +++ /dev/null @@ -1,83 +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.honeycomb.translate.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -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.core.future.FutureJVppCore; -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.v3po.rev161214.interfaces._interface.acl.Ingress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for enabling/disabling ingress ACLs on given interface based on low lever classfier model. - */ -public class AclCustomizer extends FutureJVppCustomizer implements WriterCustomizer, AclWriter { - - private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class); - private final NamingContext interfaceContext; - private final VppClassifierContextManager classifyTableContext; - - public AclCustomizer(@Nonnull final FutureJVppCore vppApi, @Nonnull final NamingContext interfaceContext, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(vppApi); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - setAcl(true, id, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final Ingress dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - throw new UnsupportedOperationException("Acl update is not supported. Please delete Acl container first."); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - setAcl(false, id, dataBefore, writeContext); - } - - private void setAcl(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final Ingress acl, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - - LOG.debug("Setting ACL(isAdd={}) on interface={}(id={}): {}", isAdd, ifName, ifIndex, acl); - - inputAclSetInterface(getFutureJVpp(), isAdd, id, acl, ifIndex, classifyTableContext, - writeContext.getMappingContext()); - LOG.debug("Successfully set ACL(isAdd={}) on interface={}(id={}): {}", isAdd, ifName, ifIndex, acl); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AclWriter.java deleted file mode 100644 index d299ec88a..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AclWriter.java +++ /dev/null @@ -1,73 +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.honeycomb.translate.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.AclBaseAttributes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -interface AclWriter extends ByteDataTranslator, JvppReplyConsumer { - - default void inputAclSetInterface(@Nonnull final FutureJVppCore futureJVppCore, final boolean isAdd, - @Nonnull final InstanceIdentifier id, @Nonnull final AclBaseAttributes acl, - @Nonnegative final int ifIndex, - @Nonnull final VppClassifierContextManager classifyTableContext, - @Nonnull final MappingContext mappingContext) throws WriteFailedException { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = booleanToByte(isAdd); - request.swIfIndex = ifIndex; - request.l2TableIndex = ~0; // skip - request.ip4TableIndex = ~0; // skip - request.ip6TableIndex = ~0; // skip - - final L2Acl l2Acl = acl.getL2Acl(); - if (l2Acl != null) { - final String tableName = checkNotNull(l2Acl.getClassifyTable(), "L2 classify table is null"); - request.l2TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); - } - final Ip4Acl ip4Acl = acl.getIp4Acl(); - if (ip4Acl != null) { - final String tableName = checkNotNull(ip4Acl.getClassifyTable(), "IPv4 classify table is null"); - request.ip4TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); - } - final Ip6Acl ip6Acl = acl.getIp6Acl(); - if (ip6Acl != null) { - final String tableName = checkNotNull(ip6Acl.getClassifyTable(), "IPv6 classify table is null"); - request.ip6TableIndex = classifyTableContext.getTableIndex(tableName, mappingContext); - } - - final CompletionStage inputAclSetInterfaceReplyCompletionStage = - futureJVppCore.inputAclSetInterface(request); - - getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizer.java deleted file mode 100644 index ec051e091..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizer.java +++ /dev/null @@ -1,89 +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.honeycomb.translate.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.v3po.rev161214.interfaces._interface.ietf.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for enabling/disabling ingress ACLs for given interface (as defined in ietf-acl model). - * - * The customizer assumes it owns classify table management for interfaces where ietf-acl container is present. Using - * low level classifier model or direct changes to classify tables in combination with ietf-acls are not supported and - * can result in unpredictable behaviour. - */ -public class IetfAclCustomizer implements WriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(IetfAclCustomizer.class); - private final IngressIetfAclWriter aclWriter; - private final NamingContext interfaceContext; - - public IetfAclCustomizer(@Nonnull final IngressIetfAclWriter aclWriter, - @Nonnull final NamingContext interfaceContext) { - this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - LOG.debug("Adding ACLs for interface={}(id={}): {}", ifName, ifIndex, dataAfter); - - final AccessLists accessLists = dataAfter.getAccessLists(); - checkArgument(accessLists != null && accessLists.getAcl() != null, - "ietf-acl container does not define acl list"); - - aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, writeContext.getMappingContext()); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("ACLs update: removing previously configured ACLs"); - deleteCurrentAttributes(id, dataBefore, writeContext); - LOG.debug("ACLs update: adding updated ACLs"); - writeCurrentAttributes(id, dataAfter, writeContext); - LOG.debug("ACLs update was successful"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String ifName = id.firstKeyOf(Interface.class).getName(); - final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); - LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); - aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java deleted file mode 100644 index b7da14ecf..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java +++ /dev/null @@ -1,118 +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.honeycomb.translate.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AbstractIetfAclWriter; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManager; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.List; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class IngressIetfAclWriter extends AbstractIetfAclWriter { - private final AclTableContextManager aclCtx; - - public IngressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { - super(futureJVppCore); - this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); - } - - @Override - public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); - checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); - final MappingEntry entry = optional.get(); - unassignClassifyTables(id, entry); - removeClassifyTables(id, entry); - aclCtx.removeEntry(swIfIndex, mappingContext); - } - - private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, - @Nonnull final MappingEntry entry) - throws WriteFailedException { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = 0; - request.swIfIndex = entry.getIndex(); - request.l2TableIndex = entry.getL2TableId(); - request.ip4TableIndex = entry.getIp4TableId(); - request.ip6TableIndex = entry.getIp6TableId(); - final CompletionStage inputAclSetInterfaceReplyCompletionStage = - jvpp.inputAclSetInterface(request); - getReplyForDelete(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); - } - - @Override - public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, - @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, - @Nonnull final MappingContext mappingContext) - throws WriteFailedException { - checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); - - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = 1; - request.swIfIndex = swIfIndex; - request.l2TableIndex = NOT_DEFINED; - request.ip4TableIndex = NOT_DEFINED; - request.ip6TableIndex = NOT_DEFINED; - - if (InterfaceMode.L2.equals(mode)) { - final List aces = getACEs(acls, writeContext, ace -> true); - request.l2TableIndex = writeAces(id, aces, defaultAction, mode, numberOfTags); - } else { - final List ip4Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp4Path)); - request.ip4TableIndex = writeAces(id, ip4Aces, defaultAction, mode, numberOfTags); - final List ip6Aces = getACEs(acls, writeContext, (AbstractIetfAclWriter::appliesToIp6Path)); - request.ip6TableIndex = writeAces(id, ip6Aces, defaultAction, mode, numberOfTags); - } - - final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) - .setIp4TableId(request.ip4TableIndex) - .setIp6TableId(request.ip6TableIndex) - .setL2TableId(request.l2TableIndex) - .build(); - aclCtx.addEntry(entry, mappingContext); - - try { - getReplyForWrite(jvpp.inputAclSetInterface(request).toCompletableFuture(), id); - } catch (WriteFailedException e) { - removeClassifyTables(id, entry); - throw e; - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java deleted file mode 100644 index bda096490..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizer.java +++ /dev/null @@ -1,93 +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.honeycomb.translate.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.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.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for enabling/disabling ingress ACLs on given sub-interface. - */ -public class SubInterfaceAclCustomizer extends FutureJVppCustomizer - implements WriterCustomizer, AclWriter { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class); - private final NamingContext interfaceContext; - private final VppClassifierContextManager classifyTableContext; - - public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore vppApi, - @Nonnull final NamingContext interfaceContext, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(vppApi); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - setAcl(true, id, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final Ingress dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - throw new UnsupportedOperationException("Acl update is not supported. Please delete Acl container first."); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - setAcl(false, id, dataBefore, writeContext); - } - - private void setAcl(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final Ingress acl, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - final String subInterfaceName = SubInterfaceUtils - .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - - LOG.debug("Setting ACL(isAdd={}) on sub-interface={}(id={}): {}", - isAdd, subInterfaceName, subInterfaceIndex, acl); - inputAclSetInterface(getFutureJVpp(), isAdd, id, acl, subInterfaceIndex, classifyTableContext, - writeContext.getMappingContext()); - LOG.debug("Successfully set ACL(isAdd={}) on sub-interface={}(id={}): {}", - isAdd, subInterfaceName, subInterfaceIndex, acl); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java deleted file mode 100644 index a9fcc83a3..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java +++ /dev/null @@ -1,108 +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.honeycomb.translate.v3po.interfaces.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils.getNumberOfTags; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for enabling/disabling ingress ACLs for given sub-interface (as defined in ietf-acl model). - * - * The customizer assumes it owns classify table management for sub-interfaces where ietf-acl container is present. - * Using low level classifier model or direct changes to classify tables in combination with ietf-acls are not supported - * and can result in unpredictable behaviour. - */ -public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIetfAclCustomizer.class); - private final IngressIetfAclWriter aclWriter; - private final NamingContext interfaceContext; - - public SubInterfaceIetfAclCustomizer(@Nonnull final IngressIetfAclWriter aclWriter, - @Nonnull final NamingContext interfaceContext) { - this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - private String getSubInterfaceName(@Nonnull final InstanceIdentifier id) { - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - return SubInterfaceUtils - .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - LOG.debug("Adding IETF-ACL for sub-interface: {}(id={}): {}", subInterfaceName, subInterfaceIndex, dataAfter); - - final AccessLists accessLists = dataAfter.getAccessLists(); - checkArgument(accessLists != null && accessLists.getAcl() != null, - "ietf-acl container does not define acl list"); - - final Optional subInterfaceOptional = - writeContext.readAfter(id.firstIdentifierOf(SubInterface.class)); - checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id); - final SubInterface subInterface = subInterfaceOptional.get(); - - aclWriter - .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, @Nonnull final Ingress dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Sub-interface ACLs update: removing previously configured ACLs"); - deleteCurrentAttributes(id, dataBefore, writeContext); - LOG.debug("Sub-interface ACLs update: adding updated ACLs"); - writeCurrentAttributes(id, dataAfter, writeContext); - LOG.debug("Sub-interface ACLs update was successful"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ingress dataBefore, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); - aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizer.java deleted file mode 100644 index 2cec90695..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizer.java +++ /dev/null @@ -1,151 +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.honeycomb.translate.v3po.interfaces.ip; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.v3po.interfaces.ip.subnet.validation.SubnetValidationException; -import io.fd.honeycomb.translate.v3po.interfaces.ip.subnet.validation.SubnetValidator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -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.core.future.FutureJVppCore; -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.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for writing {@link Address} - */ -public class Ipv4AddressCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, Ipv4Writer { - - private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressCustomizer.class); - private final NamingContext interfaceContext; - private final SubnetValidator subnetValidator; - - Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext, - @Nonnull final SubnetValidator subnetValidator) { - super(futureJVppCore); - this.interfaceContext = checkNotNull(interfaceContext, "Interface context cannot be null"); - this.subnetValidator = checkNotNull(subnetValidator, "Subnet validator cannot be null"); - } - - public Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext) { - this(futureJVppCore, interfaceContext, new SubnetValidator()); - } - - @Override - public void writeCurrentAttributes(InstanceIdentifier
id, Address dataAfter, WriteContext writeContext) - throws WriteFailedException { - - final String interfaceName = id.firstKeyOf(Interface.class).getName(); - final int interfaceIndex = interfaceContext.getIndex(interfaceName, writeContext.getMappingContext()); - - // checks whether address is not from same subnet of some address already defined on this interface - try { - - final InstanceIdentifier parentId = RWUtils.cutId(id, InstanceIdentifier.create(Ipv4.class)); - final Optional ipv4Optional = writeContext.readAfter(parentId); - - //no need to check isPresent() - we are inside of address customizer, therefore there must be Address data - //that is being processed by infrastructure - - subnetValidator.checkNotAddingToSameSubnet(ipv4Optional.get().getAddress()); - } catch (SubnetValidationException e) { - throw new WriteFailedException(id, e); - } - - setAddress(true, id, interfaceName, interfaceIndex, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(InstanceIdentifier
id, Address dataBefore, Address dataAfter, - WriteContext writeContext) throws WriteFailedException { - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, - new UnsupportedOperationException("Operation not supported")); - } - - @Override - public void deleteCurrentAttributes(InstanceIdentifier
id, Address dataBefore, WriteContext writeContext) - throws WriteFailedException { - - final String interfaceName = id.firstKeyOf(Interface.class).getName(); - final int interfaceIndex = interfaceContext.getIndex(interfaceName, writeContext.getMappingContext()); - - setAddress(false, id, interfaceName, interfaceIndex, dataBefore, writeContext); - } - - private void setAddress(boolean add, final InstanceIdentifier
id, final String interfaceName, - final int interfaceIndex, final Address address, - final WriteContext writeContext) throws WriteFailedException { - - Subnet subnet = address.getSubnet(); - - if (subnet instanceof PrefixLength) { - setPrefixLengthSubnet(add, id, interfaceName, interfaceIndex, address, (PrefixLength) subnet); - } else if (subnet instanceof Netmask) { - setNetmaskSubnet(add, id, interfaceName, interfaceIndex, address, (Netmask) subnet); - } else { - LOG.error("Unable to handle subnet of type {}", subnet.getClass()); - throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass()); - } - } - - private void setNetmaskSubnet(final boolean add, @Nonnull final InstanceIdentifier
id, - @Nonnull final String interfaceName, final int interfaceIndex, - @Nonnull final Address address, @Nonnull final Netmask subnet) - throws WriteFailedException { - - LOG.debug("Setting Subnet(subnet-mask) for interface: {}(id={}). Subnet: {}, address: {}", - interfaceName, interfaceIndex, subnet, address); - - final DottedQuad netmask = subnet.getNetmask(); - checkNotNull(netmask, "netmask value should not be null"); - - final byte subnetLength = getSubnetMaskLength(netmask.getValue()); - addDelAddress(getFutureJVpp(), add, id, interfaceIndex, address.getIp(), subnetLength); - } - - private void setPrefixLengthSubnet(final boolean add, @Nonnull final InstanceIdentifier
id, - @Nonnull final String interfaceName, final int interfaceIndex, - @Nonnull final Address address, @Nonnull final PrefixLength subnet) - throws WriteFailedException { - LOG.debug("Setting Subnet(prefix-length) for interface: {}(id={}). Subnet: {}, address: {}", - interfaceName, interfaceIndex, subnet, address); - - addDelAddress(getFutureJVpp(), add, id, interfaceIndex, address.getIp(), - subnet.getPrefixLength().byteValue()); - - LOG.debug("Subnet(prefix-length) set successfully for interface: {}(id={}). Subnet: {}, address: {}", - interfaceName, interfaceIndex, subnet, address); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Customizer.java deleted file mode 100644 index 929e82ea1..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Customizer.java +++ /dev/null @@ -1,56 +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.honeycomb.translate.v3po.interfaces.ip; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class Ipv4Customizer extends FutureJVppCustomizer implements WriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class); - - public Ipv4Customizer(final FutureJVppCore vppApi) { - super(vppApi); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ipv4 dataAfter, @Nonnull final WriteContext writeContext) { - LOG.debug("Handling Ipv4 leaves (mtu, forwarding) is not supported by VPP API. Ignoring configuration"); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ipv4 dataBefore, @Nonnull final Ipv4 dataAfter, - @Nonnull final WriteContext writeContext) { - LOG.debug("Handling Ipv4 leaves (mtu, forwarding) is not supported by VPP API. Ignoring configuration"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ipv4 dataBefore, @Nonnull final WriteContext writeContext) { - LOG.debug("Handling Ipv4 leaves (mtu, forwarding) is not supported by VPP API. Ignoring configuration"); - } - -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java deleted file mode 100644 index be4ef28cf..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java +++ /dev/null @@ -1,126 +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.honeycomb.translate.v3po.interfaces.ip; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.AddressTranslator; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.IpNeighborAddDel; -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.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * Customizer for writing {@link Neighbor} for {@link Ipv4}. - */ -public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, ByteDataTranslator, AddressTranslator, - JvppReplyConsumer { - - - private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); - final NamingContext interfaceContext; - - public Ipv4NeighbourCustomizer(final FutureJVppCore futureJVppCore, final NamingContext interfaceContext) { - super(futureJVppCore); - this.interfaceContext = interfaceContext; - } - - @Override - public void writeCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull Neighbor dataAfter, - @Nonnull WriteContext writeContext) - throws WriteFailedException { - - checkNotNull(dataAfter, "Cannot write null neighbour"); - checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found"); - - LOG.debug("Processing request for Neigbour write"); - String interfaceName = id.firstKeyOf(Interface.class).getName(); - MappingContext mappingContext = writeContext.getMappingContext(); - - checkState(interfaceContext.containsIndex(interfaceName, mappingContext), - "Mapping does not contains mapping for provider interface name ".concat(interfaceName)); - - LOG.debug("Parent interface index found"); - addDelNeighbourAndReply(id, true, - interfaceContext.getIndex(interfaceName, mappingContext), dataAfter); - LOG.info("Neighbour successfully written"); - } - - @Override - public void updateCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull Neighbor dataBefore, - @Nonnull Neighbor dataAfter, - @Nonnull WriteContext writeContext) throws WriteFailedException { - throw new UnsupportedOperationException("Operation not supported"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull Neighbor dataBefore, - @Nonnull WriteContext writeContext) - throws WriteFailedException { - - checkNotNull(dataBefore, "Cannot delete null neighbour"); - checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found"); - - LOG.debug("Processing request for Neigbour delete"); - String interfaceName = id.firstKeyOf(Interface.class).getName(); - MappingContext mappingContext = writeContext.getMappingContext(); - - checkState(interfaceContext.containsIndex(interfaceName, mappingContext), - "Mapping does not contains mapping for provider interface name %s", interfaceName); - - LOG.debug("Parent interface[{}] index found", interfaceName); - - addDelNeighbourAndReply(id, false, - interfaceContext.getIndex(interfaceName, mappingContext), dataBefore); - LOG.info("Neighbour {} successfully deleted", id); - } - - private void addDelNeighbourAndReply(InstanceIdentifier id, boolean add, int parentInterfaceIndex, - Neighbor data) throws WriteFailedException { - - IpNeighborAddDel request = new IpNeighborAddDel(); - - request.isAdd = booleanToByte(add); - request.isIpv6 = 0; - request.isStatic = 1; - request.dstAddress = ipv4AddressNoZoneToArray(data.getIp()); - request.macAddress = parseMac(data.getLinkLayerAddress().getValue()); - request.swIfIndex = parentInterfaceIndex; - - //TODO HONEYCOMB-182 if it is necessary for future use ,make adjustments to be able to set vrfid - //request.vrfId - getReplyForWrite(getFutureJVpp().ipNeighborAddDel(request).toCompletableFuture(), id); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Writer.java deleted file mode 100644 index 788deab3b..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Writer.java +++ /dev/null @@ -1,108 +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.honeycomb.translate.v3po.interfaces.ip; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.Ipv4Translator; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddress; -import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddressReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Utility class providing Ipv4 CUD support. - */ -public interface Ipv4Writer extends ByteDataTranslator, Ipv4Translator, JvppReplyConsumer { - - int DOTTED_QUAD_MASK_LENGTH = 4; - int IPV4_ADDRESS_PART_BITS_COUNT = 8; - int NETMASK_PART_LIMIT = 256; // 2 power to 8 - - default void addDelAddress(@Nonnull final FutureJVppCore futureJVppCore, final boolean add, - final InstanceIdentifier id, - @Nonnegative final int ifaceId, - @Nonnull final Ipv4AddressNoZone address, @Nonnegative final byte prefixLength) - throws WriteFailedException { - checkArgument(prefixLength > 0, "Invalid prefix length"); - checkNotNull(address, "address should not be null"); - - final byte[] addressBytes = ipv4AddressNoZoneToArray(address); - - final CompletionStage swInterfaceAddDelAddressReplyCompletionStage = - futureJVppCore.swInterfaceAddDelAddress( - getSwInterfaceAddDelAddressRequest(ifaceId, booleanToByte(add) /* isAdd */, - (byte) 0 /* isIpv6 */, (byte) 0 /* delAll */, prefixLength, addressBytes)); - - getReplyForWrite(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture(), id); - } - - default SwInterfaceAddDelAddress getSwInterfaceAddDelAddressRequest(final int swIfc, final byte isAdd, - final byte ipv6, final byte deleteAll, - final byte length, final byte[] addr) { - final SwInterfaceAddDelAddress swInterfaceAddDelAddress = new SwInterfaceAddDelAddress(); - swInterfaceAddDelAddress.swIfIndex = swIfc; - swInterfaceAddDelAddress.isAdd = isAdd; - swInterfaceAddDelAddress.isIpv6 = ipv6; - swInterfaceAddDelAddress.delAll = deleteAll; - swInterfaceAddDelAddress.address = addr; - swInterfaceAddDelAddress.addressLength = length; - return swInterfaceAddDelAddress; - } - - /** - * Returns the prefix size in bits of the specified subnet mask. Example: For the subnet mask 255.255.255.128 it - * returns 25 while for 255.0.0.0 it returns 8. If the passed subnetMask array is not complete or contains not only - * leading ones, IllegalArgumentExpression is thrown - * - * @param mask the subnet mask in dot notation 255.255.255.255 - * @return the prefix length as number of bits - */ - default byte getSubnetMaskLength(final String mask) { - String[] maskParts = mask.split("\\."); - - checkArgument(maskParts.length == DOTTED_QUAD_MASK_LENGTH, - "Network mask %s is not in Quad Dotted Decimal notation!", mask); - - long maskAsNumber = 0; - for (int i = 0; i < DOTTED_QUAD_MASK_LENGTH; i++) { - maskAsNumber <<= IPV4_ADDRESS_PART_BITS_COUNT; - int value = Integer.parseInt(maskParts[i]); - checkArgument(value < NETMASK_PART_LIMIT, "Network mask %s contains invalid number(s) over 255!", mask); - checkArgument(value >= 0, "Network mask %s contains invalid negative number(s)!", mask); - maskAsNumber += value; - } - - String bits = Long.toBinaryString(maskAsNumber); - checkArgument(bits.length() == IPV4_ADDRESS_PART_BITS_COUNT * DOTTED_QUAD_MASK_LENGTH, - "Incorrect network mask %s", mask); - final int leadingOnes = bits.indexOf('0'); - checkArgument(leadingOnes != -1, "Broadcast address %s is not allowed!", mask); - checkArgument(bits.substring(leadingOnes).indexOf('1') == -1, - "Non-contiguous network mask %s is not allowed!", mask); - return (byte) leadingOnes; - } - -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv6Customizer.java deleted file mode 100644 index 094957a91..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv6Customizer.java +++ /dev/null @@ -1,55 +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.honeycomb.translate.v3po.interfaces.ip; - -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class Ipv6Customizer extends FutureJVppCustomizer implements WriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(Ipv6Customizer.class); - - public Ipv6Customizer(final FutureJVppCore vppApi) { - super(vppApi); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ipv6 dataAfter, @Nonnull final WriteContext writeContext) { - LOG.warn("Unsupported, ignoring configuration {}", dataAfter); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ipv6 dataBefore, @Nonnull final Ipv6 dataAfter, - @Nonnull final WriteContext writeContext) { - LOG.warn("Unsupported, ignoring configuration {}", dataAfter); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final Ipv6 dataBefore, @Nonnull final WriteContext writeContext) { - LOG.warn("Unsupported, ignoring configuration delete {}", id); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java deleted file mode 100644 index 52c541198..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.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.honeycomb.translate.v3po.interfaces.ip; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -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.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.DottedQuad; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.Subnet; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.Netmask; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Write customizer for sub-interface {@link Address} - */ -public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, Ipv4Writer { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class); - private final NamingContext interfaceContext; - - public SubInterfaceIpv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.interfaceContext = checkNotNull(interfaceContext, "interface context should not be null"); - } - - @Override - public void writeCurrentAttributes(InstanceIdentifier
id, Address dataAfter, WriteContext writeContext) - throws WriteFailedException { - setAddress(true, id, dataAfter, writeContext); - } - - @Override - public void updateCurrentAttributes(InstanceIdentifier
id, Address dataBefore, Address dataAfter, - WriteContext writeContext) throws WriteFailedException { - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, - new UnsupportedOperationException("Operation not supported")); - } - - @Override - public void deleteCurrentAttributes(InstanceIdentifier
id, Address dataBefore, WriteContext writeContext) - throws WriteFailedException { - setAddress(false, id, dataBefore, writeContext); - } - - private void setAddress(boolean add, final InstanceIdentifier
id, final Address address, - final WriteContext writeContext) throws WriteFailedException { - - final String interfaceName = id.firstKeyOf(Interface.class).getName(); - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - - Subnet subnet = address.getSubnet(); - - if (subnet instanceof PrefixLength) { - setPrefixLengthSubnet(add, id, interfaceName, subInterfaceIndex, address, (PrefixLength) subnet); - } else if (subnet instanceof Netmask) { - setNetmaskSubnet(add, id, interfaceName, subInterfaceIndex, address, (Netmask) subnet); - } else { - LOG.error("Unable to handle subnet of type {}", subnet.getClass()); - throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass()); - } - } - - private String getSubInterfaceName(@Nonnull final InstanceIdentifier
id) { - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - return SubInterfaceUtils - .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - } - - private void setNetmaskSubnet(final boolean add, @Nonnull final InstanceIdentifier
id, - @Nonnull final String subInterfaceName, final int subInterfaceIndex, - @Nonnull final Address address, @Nonnull final Netmask subnet) - throws WriteFailedException { - - LOG.debug("Setting Subnet(subnet-mask) for sub-interface: {}(id={}). Subnet: {}, address: {}", - subInterfaceName, subInterfaceIndex, subnet, address); - - final DottedQuad netmask = subnet.getNetmask(); - checkNotNull(netmask, "netmask value should not be null"); - - final byte subnetLength = getSubnetMaskLength(netmask.getValue()); - addDelAddress(getFutureJVpp(), add, id, subInterfaceIndex, address.getIp(), subnetLength); - } - - private void setPrefixLengthSubnet(final boolean add, @Nonnull final InstanceIdentifier
id, - @Nonnull final String subInterfaceName, final int subInterfaceIndex, - @Nonnull final Address address, @Nonnull final PrefixLength subnet) - throws WriteFailedException { - LOG.debug("Setting Subnet(prefix-length) for sub-interface: {}(id={}). Subnet: {}, address: {}", - subInterfaceName, subInterfaceIndex, subnet, address); - - addDelAddress(getFutureJVpp(), add, id, subInterfaceIndex, address.getIp(), - subnet.getPrefixLength().byteValue()); - - LOG.debug("Subnet(prefix-length) set successfully for sub-interface: {}(id={}). Subnet: {}, address: {}", - subInterfaceName, subInterfaceIndex, subnet, address); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidationException.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidationException.java deleted file mode 100644 index ae8291027..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidationException.java +++ /dev/null @@ -1,50 +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.honeycomb.translate.v3po.interfaces.ip.subnet.validation; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Collection; -import javax.annotation.Nonnull; -import org.apache.commons.lang3.StringUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; - -/** - * Thrown as negative result of subnet validation - */ -public class SubnetValidationException extends Exception { - - private SubnetValidationException(@Nonnull final String message) { - super(message); - } - - public static SubnetValidationException forConflictingData(@Nonnull final Short prefix, @Nonnull Collection
addresses) { - return new SubnetValidationException( - "Attempt to define multiple addresses for same subnet[prefixLen = " + prefixToString(prefix) + "], " - + "addresses : " + addressesToString(addresses)); - } - - private static String prefixToString(final Short prefix) { - return checkNotNull(prefix, "Cannot create " + SubnetValidationException.class.getName() + " for null prefix") - .toString(); - } - - private static String addressesToString(final Collection
addresses) { - return StringUtils.join(checkNotNull(addresses, - "Cannot create " + SubnetValidationException.class.getName() + " for null address list"), " | "); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidator.java deleted file mode 100644 index a314eaf14..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidator.java +++ /dev/null @@ -1,80 +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.honeycomb.translate.v3po.interfaces.ip.subnet.validation; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Function; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; -import io.fd.honeycomb.translate.v3po.interfaces.ip.Ipv4Writer; -import java.util.List; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength; - -/** - * Validator for detecting if there is an attempt to assign multiple addresses from same subnet - */ -public class SubnetValidator implements Ipv4Writer { - - /** - * Checks whether data provided for writing are not in collision with already existing data - */ - public void checkNotAddingToSameSubnet(@Nonnull final List
addresses) - throws SubnetValidationException { - - final Multimap prefixLengthRegister = Multimaps.index(addresses, toPrefixLength()); - final int keySetSize = prefixLengthRegister.keySet().size(); - - if (keySetSize == 0 || keySetSize == addresses.size()) { - //this means that every key is unique(has only one value) or no addresses were prefix-length based ,so there is no conflict - return; - } - - //finds conflicting prefix - final Short conflictingPrefix = prefixLengthRegister.keySet() - .stream() - .filter(a -> prefixLengthRegister.get(a).size() > 1) - .findFirst() - .get(); - - //and reports it with affected addresses - throw SubnetValidationException - .forConflictingData(conflictingPrefix, prefixLengthRegister.get(conflictingPrefix)); - } - - private Function toPrefixLength() { - return (final Address address) -> { - final Subnet subnet = address.getSubnet(); - - if (subnet instanceof PrefixLength) { - return ((PrefixLength) subnet).getPrefixLength(); - } - - if (address.getSubnet() instanceof Netmask) { - return (short) getSubnetMaskLength( - checkNotNull(((Netmask) subnet).getNetmask(), "No netmask defined for %s", subnet) - .getValue()); - } - - throw new IllegalArgumentException("Unsupported subnet : " + subnet); - }; - } -} 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 deleted file mode 100644 index 8b6ccb128..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizer.java +++ /dev/null @@ -1,130 +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.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.rev161214.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/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/EthernetCustomizer.java deleted file mode 100644 index b2533a230..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/EthernetCustomizer.java +++ /dev/null @@ -1,108 +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.honeycomb.translate.v3po.interfacesstate; - -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.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Ethernet; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.EthernetBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class EthernetCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, InterfaceDataTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class); - private NamingContext interfaceContext; - - public EthernetCustomizer(@Nonnull final FutureJVppCore jvpp, - @Nonnull final NamingContext interfaceContext) { - super(jvpp); - this.interfaceContext = interfaceContext; - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, - @Nonnull final Ethernet readValue) { - ((VppInterfaceStateAugmentationBuilder) parentBuilder).setEthernet(readValue); - } - - @Nonnull - @Override - public EthernetBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new EthernetBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final EthernetBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - - final InterfaceKey key = id.firstKeyOf(Interface.class); - final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), - interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache(), LOG); - - if (iface.linkMtu != 0) { - builder.setMtu((int) iface.linkMtu); - } - - switch (iface.linkDuplex) { - case 1: - builder.setDuplex(Ethernet.Duplex.Half); - break; - case 2: - builder.setDuplex(Ethernet.Duplex.Full); - break; - default: - break; - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final Ethernet readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.EthernetBuilder() - .setMtu(readValue.getMtu()) - .build()); - } - - private InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Ethernet.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/GreCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/GreCustomizer.java deleted file mode 100644 index 2fb94c1e1..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/GreCustomizer.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2016 Intel 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.interfacesstate; - -import static com.google.common.base.Preconditions.checkState; - -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.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.GreTunnelDetails; -import io.fd.vpp.jvpp.core.dto.GreTunnelDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.GreTunnelDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.GreTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Gre; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.GreBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class GreCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, InterfaceDataTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(GreCustomizer.class); - private NamingContext interfaceContext; - - public GreCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { - super(jvpp); - this.interfaceContext = interfaceContext; - } - - @Override - public void merge(@Nonnull Builder parentBuilder, - @Nonnull Gre readValue) { - ((VppInterfaceStateAugmentationBuilder) parentBuilder).setGre(readValue); - } - - @Nonnull - @Override - public GreBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new GreBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final GreBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, GreTunnel.class, LOG)) { - return; - } - - LOG.debug("Reading attributes for gre tunnel: {}", key.getName()); - // Dump just a single - final GreTunnelDump request = new GreTunnelDump(); - request.swIfIndex = index; - - final CompletionStage swInterfaceGreDetailsReplyDumpCompletionStage = - getFutureJVpp().greTunnelDump(request); - final GreTunnelDetailsReplyDump reply = - getReplyForRead(swInterfaceGreDetailsReplyDumpCompletionStage.toCompletableFuture(), id); - - // VPP keeps gre tunnel interfaces even after they were deleted (optimization) - // However there ar no longer any gre tunnel specific fields assigned to it and this call - // returns nothing - if (reply == null || reply.greTunnelDetails == null || reply.greTunnelDetails.isEmpty()) { - LOG.debug( - "Gre tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + - "after delete", key.getName(), index); - return; - } - - checkState(reply.greTunnelDetails.size() == 1, - "Unexpected number of returned gre tunnels: {} for tunnel: {}", reply.greTunnelDetails, - key.getName()); - LOG.trace("Gre tunnel: {} attributes returned from VPP: {}", key.getName(), reply); - - final GreTunnelDetails swInterfaceGreDetails = reply.greTunnelDetails.get(0); - if (swInterfaceGreDetails.isIpv6 == 1) { - final Ipv6Address dstIpv6 = - new Ipv6Address(parseAddress(swInterfaceGreDetails.dstAddress).getHostAddress()); - builder.setDst(new IpAddress(dstIpv6)); - final Ipv6Address srcIpv6 = - new Ipv6Address(parseAddress(swInterfaceGreDetails.srcAddress).getHostAddress()); - builder.setSrc(new IpAddress(srcIpv6)); - } else { - final byte[] dstBytes = Arrays.copyOfRange(swInterfaceGreDetails.dstAddress, 0, 4); - final Ipv4Address dstIpv4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); - builder.setDst(new IpAddress(dstIpv4)); - final byte[] srcBytes = Arrays.copyOfRange(swInterfaceGreDetails.srcAddress, 0, 4); - final Ipv4Address srcIpv4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); - builder.setSrc(new IpAddress(srcIpv4)); - } - builder.setOuterFibId((long) swInterfaceGreDetails.outerFibId); - LOG.debug("Gre tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); - } - - @Nonnull - private static InetAddress parseAddress(@Nonnull final byte[] addr) { - try { - return InetAddress.getByAddress(addr); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e); - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final Gre readValue, @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.GreBuilder() - .setDst(readValue.getDst()) - .setSrc(readValue.getSrc()) - .setOuterFibId(readValue.getOuterFibId()) - .build()); - } - - private InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterconnectionReadUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterconnectionReadUtils.java deleted file mode 100644 index be4eca66f..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterconnectionReadUtils.java +++ /dev/null @@ -1,125 +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.honeycomb.translate.v3po.interfacesstate; - -import static com.google.common.base.Preconditions.checkState; -import static java.util.Objects.requireNonNull; - -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; -import io.fd.vpp.jvpp.core.dto.BridgeDomainSwIfDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class providing Interconnection read support. - */ -final class InterconnectionReadUtils implements InterfaceDataTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(InterconnectionReadUtils.class); - - private final FutureJVppCore futureJVppCore; - private final NamingContext interfaceContext; - private final NamingContext bridgeDomainContext; - - InterconnectionReadUtils(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext, - @Nonnull final NamingContext bridgeDomainContext) { - this.futureJVppCore = requireNonNull(futureJVppCore, "futureJVppCore should not be null"); - this.interfaceContext = requireNonNull(interfaceContext, "interfaceContext should not be null"); - this.bridgeDomainContext = requireNonNull(bridgeDomainContext, "bridgeDomainContext should not be null"); - } - - @Nullable - Interconnection readInterconnection(@Nonnull final InstanceIdentifier id, @Nonnull final String ifaceName, - @Nonnull final ReadContext ctx) - throws ReadFailedException { - final int ifaceId = interfaceContext.getIndex(ifaceName, ctx.getMappingContext()); - - final SwInterfaceDetails iface = getVppInterfaceDetails(futureJVppCore, id, ifaceName, - ifaceId, ctx.getModificationCache(), LOG); - LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface); - - final BridgeDomainDetailsReplyDump dumpReply = getDumpReply(id); - final Optional bdForInterface = getBridgeDomainForInterface(ifaceId, dumpReply); - if (bdForInterface.isPresent()) { - final BridgeDomainSwIfDetails bdSwIfDetails = bdForInterface.get(); - final BridgeBasedBuilder bbBuilder = new BridgeBasedBuilder(); - bbBuilder.setBridgeDomain(bridgeDomainContext.getName(bdSwIfDetails.bdId, ctx.getMappingContext())); - - // Set BVI if the bridgeDomainDetails.bviSwIfIndex == current sw if index - final Optional bridgeDomainForInterface = - getBridgeDomainForInterface(dumpReply, bdForInterface.get().bdId); - // Since we already found an interface assigned to a bridge domain, the details for BD must be present - checkState(bridgeDomainForInterface.isPresent()); - if (bridgeDomainForInterface.get().bviSwIfIndex == ifaceId) { - bbBuilder.setBridgedVirtualInterface(true); - } else { - bbBuilder.setBridgedVirtualInterface(false); - } - - if (bdSwIfDetails.shg != 0) { - bbBuilder.setSplitHorizonGroup((short) bdSwIfDetails.shg); - } - return bbBuilder.build(); - } - // TODO HONEYCOMB-190 is there a way to check if interconnection is XconnectBased? - - return null; - } - - private Optional getBridgeDomainForInterface(final int ifaceId, - final BridgeDomainDetailsReplyDump reply) { - if (null == reply || null == reply.bridgeDomainSwIfDetails || reply.bridgeDomainSwIfDetails.isEmpty()) { - return Optional.empty(); - } - // interface can be added to only one BD only - return reply.bridgeDomainSwIfDetails.stream().filter(a -> a.swIfIndex == ifaceId).findFirst(); - } - - private Optional getBridgeDomainForInterface(final BridgeDomainDetailsReplyDump reply, - int bdId) { - return reply.bridgeDomainDetails.stream().filter(a -> a.bdId == bdId).findFirst(); - } - - private BridgeDomainDetailsReplyDump getDumpReply(@Nonnull final InstanceIdentifier id) - throws ReadFailedException { - // We need to perform full bd dump, because there is no way - // to ask VPP for BD details given interface id/name (TODO HONEYCOMB-190 add it to vpp.api?) - // TODO HONEYCOMB-190 cache dump result - final BridgeDomainDump request = new BridgeDomainDump(); - request.bdId = -1; - - final CompletableFuture bdCompletableFuture = - futureJVppCore.bridgeDomainSwIfDump(request).toCompletableFuture(); - return getReplyForRead(bdCompletableFuture, id); - - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceCustomizer.java deleted file mode 100644 index 4308f34a0..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceCustomizer.java +++ /dev/null @@ -1,232 +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.honeycomb.translate.v3po.interfacesstate; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.ModificationCache; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; -import io.fd.honeycomb.translate.v3po.DisabledInterfacesManager; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for reading ietf-interfaces:interfaces-state/interface. - */ -public class InterfaceCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, ByteDataTranslator, - InterfaceDataTranslator { - - public static final String DUMPED_IFCS_CONTEXT_KEY = - InterfaceCustomizer.class.getName() + "dumpedInterfacesDuringGetAllIds"; - private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); - private final NamingContext interfaceNamingContext; - private final DisabledInterfacesManager interfaceDisableContext; - - public InterfaceCustomizer(@Nonnull final FutureJVppCore jvpp, - @Nonnull final NamingContext interfaceNamingContext, - @Nonnull final DisabledInterfacesManager interfaceDisableContext) { - super(jvpp); - this.interfaceNamingContext = interfaceNamingContext; - this.interfaceDisableContext = interfaceDisableContext; - } - - public static void cacheInterfaceDump(final @Nonnull ReadContext context, final SwInterfaceDetailsReplyDump ifaces) { - context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); - } - - @Nonnull - @SuppressWarnings("unchecked") - public static Map getCachedInterfaceDump(@Nonnull final ModificationCache ctx) { - return ctx.get(DUMPED_IFCS_CONTEXT_KEY) == null - ? new HashMap<>() - // allow customizers to update the cache - : (Map) ctx.get(DUMPED_IFCS_CONTEXT_KEY); - } - - private static boolean isRegularInterface(final SwInterfaceDetails iface) { - return iface.subId == 0; - } - - @Nonnull - @Override - public InterfaceBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new InterfaceBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull InterfaceBuilder builder, - @Nonnull ReadContext ctx) throws ReadFailedException { - LOG.debug("Reading attributes for interface: {}", id); - final String ifaceName = id.firstKeyOf(id.getTargetType()).getName(); - - final int index = interfaceNamingContext.getIndex(ifaceName, ctx.getMappingContext()); - - // Ignore disabled interface (such as deleted VXLAN tunnels) - if (interfaceDisableContext.isInterfaceDisabled(index, ctx.getMappingContext())) { - LOG.debug("Skipping disabled interface: {}", id); - return; - } - - // Pass cached details from getAllIds to getDetails to avoid additional dumps - final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, ifaceName, - index, ctx.getModificationCache(), LOG); - LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface); - - if (!isRegularInterface(iface)) { - LOG.debug("Interface: {} is a sub-interface. Ignoring read request.", ifaceName); - return; - } - - builder.setName(ifaceName); - builder.setType(getInterfaceType(new String(iface.interfaceName).intern())); - builder.setIfIndex(vppIfIndexToYang(iface.swIfIndex)); - builder.setAdminStatus(1 == iface.adminUpDown - ? AdminStatus.Up - : AdminStatus.Down); - builder.setOperStatus(1 == iface.linkUpDown - ? OperStatus.Up - : OperStatus.Down); - if (0 != iface.linkSpeed) { - builder.setSpeed(vppInterfaceSpeedToYang(iface.linkSpeed)); - } - if (iface.l2AddressLength == 6) { - builder.setPhysAddress(new PhysAddress(vppPhysAddrToYang(iface.l2Address))); - } - LOG.trace("Base attributes read for interface: {} as: {}", ifaceName, builder); - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext context) throws ReadFailedException { - final List interfacesKeys; - LOG.trace("Dumping all interfaces to get all IDs"); - - final SwInterfaceDump request = new SwInterfaceDump(); - request.nameFilter = "".getBytes(); - request.nameFilterValid = 0; - - final CompletableFuture swInterfaceDetailsReplyDumpCompletableFuture = - getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); - final SwInterfaceDetailsReplyDump ifaces = - getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); - - if (null == ifaces || null == ifaces.swInterfaceDetails) { - LOG.debug("No interfaces for :{} found in VPP", id); - return Collections.emptyList(); - } - - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - cacheInterfaceDump(context, ifaces); - - final MappingContext mappingCtx = context.getMappingContext(); - final Set interfacesIdxs = ifaces.swInterfaceDetails.stream() - .filter(elt -> elt != null) - // Filter out disabled interfaces, dont read them - // This also prevents child readers in being invoked such as vxlan (which relies on disabling interfaces) - .filter(elt -> !interfaceDisableContext - .isInterfaceDisabled(elt.swIfIndex, mappingCtx)) - .map((elt) -> { - // Store interface name from VPP in context if not yet present - if (!interfaceNamingContext.containsName(elt.swIfIndex, mappingCtx)) { - interfaceNamingContext.addName(elt.swIfIndex, toString(elt.interfaceName), - mappingCtx); - } - LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP", - interfaceNamingContext.getName(elt.swIfIndex, mappingCtx), - elt.interfaceName, - elt.swIfIndex); - - return elt; - }) - // filter out sub-interfaces - .filter(InterfaceCustomizer::isRegularInterface) - .map(elt -> elt.swIfIndex) - .collect(Collectors.toSet()); - - // Clean disabled interfaces list - interfaceDisableContext.getDisabledInterfaces(mappingCtx).stream() - // Find indices not currently in VPP - .filter(interfacesIdxs::contains) - // Remove from disabled list ... not disabled if not existing - .forEach(idx -> interfaceDisableContext.removeDisabledInterface(idx, mappingCtx)); - - // Transform indices to keys - interfacesKeys = interfacesIdxs.stream() - .map(index -> new InterfaceKey(interfaceNamingContext.getName(index, context.getMappingContext()))) - .collect(Collectors.toList()); - - LOG.debug("Interfaces found in VPP: {}", interfacesKeys); - return interfacesKeys; - } - - @Override - public void merge(@Nonnull final org.opendaylight.yangtools.concepts.Builder builder, - @Nonnull final List readData) { - ((InterfacesStateBuilder) builder).setInterface(readData); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final Interface readValue, @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder() - .setName(readValue.getName()) - .setType(readValue.getType()) - .setEnabled(AdminStatus.Up.equals(readValue.getAdminStatus())) - // Not present in interfaces-state - // .setLinkUpDownTrapEnable() - .build()); - } - - public static InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InstanceIdentifier.create(Interfaces.class).child( - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface.class, - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey( - id.firstKeyOf(Interface.class).getName())); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslator.java deleted file mode 100644 index 2864c6e6a..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslator.java +++ /dev/null @@ -1,287 +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.honeycomb.translate.v3po.interfacesstate; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -import io.fd.honeycomb.translate.ModificationCache; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.math.BigInteger; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.CompletionStage; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Gauge64; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.GreTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Loopback; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; - -public interface InterfaceDataTranslator extends ByteDataTranslator, JvppReplyConsumer { - - Gauge64 vppLinkSpeed0 = new Gauge64(BigInteger.ZERO); - Gauge64 vppLinkSpeed1 = new Gauge64(BigInteger.valueOf(10L * 1000000)); - Gauge64 vppLinkSpeed2 = new Gauge64(BigInteger.valueOf(100L * 1000000)); - Gauge64 vppLinkSpeed4 = new Gauge64(BigInteger.valueOf(1000L * 1000000)); - Gauge64 vppLinkSpeed8 = new Gauge64(BigInteger.valueOf(10000L * 1000000)); - Gauge64 vppLinkSpeed16 = new Gauge64(BigInteger.valueOf(40000L * 1000000)); - Gauge64 vppLinkSpeed32 = new Gauge64(BigInteger.valueOf(100000L * 1000000)); - - char[] HEX_CHARS = "0123456789abcdef".toCharArray(); - - int PHYSICAL_ADDRESS_LENGTH = 6; - - Collector SINGLE_ITEM_COLLECTOR = - RWUtils.singleItemCollector(); - - /** - * Convert VPP's link speed bitmask to Yang type. 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G - * - * @param vppLinkSpeed Link speed in bitmask format from VPP. - * @return Converted value from VPP link speed - */ - default Gauge64 vppInterfaceSpeedToYang(byte vppLinkSpeed) { - switch (vppLinkSpeed) { - case 1: - return vppLinkSpeed1; - case 2: - return vppLinkSpeed2; - case 4: - return vppLinkSpeed4; - case 8: - return vppLinkSpeed8; - case 16: - return vppLinkSpeed16; - case 32: - return vppLinkSpeed32; - default: - return vppLinkSpeed0; - } - } - - default void appendHexByte(final StringBuilder sb, final byte b) { - final int v = b & 0xFF; - sb.append(HEX_CHARS[v >>> 4]); - sb.append(HEX_CHARS[v & 15]); - } - - /** - * Reads first 6 bytes of supplied byte array and converts to string as Yang dictates

Replace later with - * https://git.opendaylight.org/gerrit/#/c/34869/10/model/ietf/ietf-type- util/src/main/ - * java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java - * - * @param vppPhysAddress byte array of bytes in big endian order, constructing the network IF physical address. - * @return String like "aa:bb:cc:dd:ee:ff" - * @throws NullPointerException if vppPhysAddress is null - * @throws IllegalArgumentException if vppPhysAddress.length < 6 - */ - default String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) { - return vppPhysAddrToYang(vppPhysAddress, 0); - } - - default String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress, final int startIndex) { - Objects.requireNonNull(vppPhysAddress, "Empty physical address bytes"); - final int endIndex = startIndex + PHYSICAL_ADDRESS_LENGTH; - checkArgument(endIndex <= vppPhysAddress.length, - "Invalid physical address size (%s) for given startIndex (%s), expected >= %s", vppPhysAddress.length, - startIndex, endIndex); - return printHexBinary(vppPhysAddress, startIndex, endIndex); - } - - default String printHexBinary(@Nonnull final byte[] bytes) { - Objects.requireNonNull(bytes, "bytes array should not be null"); - return printHexBinary(bytes, 0, bytes.length); - } - - default String printHexBinary(@Nonnull final byte[] bytes, final int startIndex, final int endIndex) { - StringBuilder str = new StringBuilder(); - - appendHexByte(str, bytes[startIndex]); - for (int i = startIndex + 1; i < endIndex; i++) { - str.append(":"); - appendHexByte(str, bytes[i]); - } - - return str.toString(); - } - - /** - * VPP's interface index is counted from 0, whereas ietf-interface's if-index is from 1. This function converts from - * VPP's interface index to YANG's interface index. - * - * @param vppIfIndex the sw interface index VPP reported. - * @return VPP's interface index incremented by one - */ - default int vppIfIndexToYang(int vppIfIndex) { - return vppIfIndex + 1; - } - - /** - * This function does the opposite of what {@link #vppIfIndexToYang(int)} does. - * - * @param yangIfIndex if-index from ietf-interfaces. - * @return VPP's representation of the if-index - */ - default int yangIfIndexToVpp(int yangIfIndex) { - checkArgument(yangIfIndex >= 1, "YANG if-index has invalid value %s", yangIfIndex); - return yangIfIndex - 1; - } - - - /** - * Queries VPP for interface description given interface key. - * - * @param futureJVppCore VPP Java Future API - * @param id InstanceIdentifier, which is passed in ReadFailedException - * @param name interface name - * @param index VPP index of the interface - * @param ctx per-tx scope context containing cached dump with all the interfaces. If the cache is not - * available or outdated, another dump will be performed. - * @return SwInterfaceDetails DTO or null if interface was not found - * @throws IllegalArgumentException If interface cannot be found - * @throws ReadFailedException If read operation had failed - */ - @Nonnull - default SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final InstanceIdentifier id, - @Nonnull final String name, final int index, - @Nonnull final ModificationCache ctx, - @Nonnull final Logger callerLogger) - throws ReadFailedException { - requireNonNull(futureJVppCore, "futureJVppCore should not be null"); - requireNonNull(name, "name should not be null"); - requireNonNull(ctx, "ctx should not be null"); - - final SwInterfaceDump request = new SwInterfaceDump(); - request.nameFilter = name.getBytes(); - request.nameFilterValid = 1; - - final Map allInterfaces = InterfaceCustomizer.getCachedInterfaceDump(ctx); - - // Returned cached if available - if (allInterfaces.containsKey(index)) { - return allInterfaces.get(index); - } - - SwInterfaceDetailsReplyDump ifaces; - - CompletionStage requestFuture = futureJVppCore.swInterfaceDump(request); - ifaces = getReplyForRead(requestFuture.toCompletableFuture(), id); - if (null == ifaces || null == ifaces.swInterfaceDetails || ifaces.swInterfaceDetails.isEmpty()) { - request.nameFilterValid = 0; - - callerLogger.warn("VPP returned null instead of interface by key {} and its not cached", name); - callerLogger.warn("Iterating through all the interfaces to find interface: {}", name); - - // Or else just perform full dump and do inefficient filtering - requestFuture = futureJVppCore.swInterfaceDump(request); - ifaces = getReplyForRead(requestFuture.toCompletableFuture(), id); - - // Update the cache - allInterfaces.clear(); - allInterfaces - .putAll(ifaces.swInterfaceDetails.stream().collect(Collectors.toMap(d -> d.swIfIndex, d -> d))); - - if (allInterfaces.containsKey(index)) { - return allInterfaces.get(index); - } - throw new IllegalArgumentException("Unable to find interface " + name); - } - - // SwInterfaceDump's name filter does prefix match, so we need additional filtering: - final SwInterfaceDetails iface = - ifaces.swInterfaceDetails.stream().filter(d -> d.swIfIndex == index).collect(SINGLE_ITEM_COLLECTOR); - allInterfaces.put(index, iface); // update the cache - return iface; - } - - /** - * Determine interface type based on its VPP name (relying on VPP's interface naming conventions) - * - * @param interfaceName VPP generated interface name - * @return Interface type - */ - @Nonnull - default Class getInterfaceType(@Nonnull final String interfaceName) { - if (interfaceName.startsWith("tap")) { - return Tap.class; - } - - if (interfaceName.startsWith("vxlan_gpe")) { - return VxlanGpeTunnel.class; - } - - if (interfaceName.startsWith("vxlan")) { - return VxlanTunnel.class; - } - - if (interfaceName.startsWith("gre")) { - return GreTunnel.class; - } - - if (interfaceName.startsWith("VirtualEthernet")) { - return VhostUser.class; - } - - if (interfaceName.startsWith("loop")) { - return Loopback.class; - } - - return EthernetCsmacd.class; - } - - /** - * Check interface type. Uses interface details from VPP to determine. Uses {@link - * #getVppInterfaceDetails(FutureJVppCore, InstanceIdentifier, String, int, ModificationCache, Logger)} internally - * so tries to utilize cache before asking VPP. - */ - default boolean isInterfaceOfType(@Nonnull final FutureJVppCore jvpp, - @Nonnull final ModificationCache cache, - @Nonnull final InstanceIdentifier id, - final int index, - @Nonnull final Class ifcType, - @Nonnull final Logger callerLogger) - throws ReadFailedException { - final String name = id.firstKeyOf(Interface.class).getName(); - final SwInterfaceDetails vppInterfaceDetails = - getVppInterfaceDetails(jvpp, id, name, index, cache, callerLogger); - - return isInterfaceOfType(ifcType, vppInterfaceDetails); - } - - default boolean isInterfaceOfType(final Class ifcType, - final SwInterfaceDetails cachedDetails) { - return ifcType.equals(getInterfaceType(toString(cachedDetails.interfaceName))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/L2Customizer.java deleted file mode 100644 index 2a29fddeb..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/L2Customizer.java +++ /dev/null @@ -1,116 +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.honeycomb.translate.v3po.interfacesstate; - -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.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBased; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBased; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBasedBuilder; -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; - -/** - * Customizer for reading ietf-interfaces:interfaces-state/interface/iface_name/v3po:l2 - */ -public class L2Customizer extends FutureJVppCustomizer implements InitializingReaderCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class); - private final InterconnectionReadUtils icReadUtils; - - public L2Customizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext, - @Nonnull final NamingContext bridgeDomainContext) { - super(futureJVppCore); - this.icReadUtils = new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final L2 readValue) { - ((VppInterfaceStateAugmentationBuilder) parentBuilder).setL2(readValue); - } - - @Nonnull - @Override - public L2Builder getBuilder(@Nonnull final InstanceIdentifier id) { - return new L2Builder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2Builder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - - LOG.debug("Reading attributes for L2: {}", id); - final InterfaceKey key = id.firstKeyOf(Interface.class); - final String ifaceName = key.getName(); - builder.setInterconnection(icReadUtils.readInterconnection(id, ifaceName, ctx)); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final L2 readValue, - @Nonnull final ReadContext ctx) { - final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder - l2Builder = - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder(); - - final Interconnection interconnection = readValue.getInterconnection(); - if (interconnection != null) { - if (interconnection instanceof XconnectBased) { - final XconnectBasedBuilder xconnectBasedBuilder = new XconnectBasedBuilder(); - xconnectBasedBuilder.setXconnectOutgoingInterface( - ((XconnectBased) interconnection).getXconnectOutgoingInterface()); - l2Builder.setInterconnection(xconnectBasedBuilder.build()); - } else if (interconnection instanceof BridgeBased) { - final BridgeBasedBuilder bridgeBasedBuilder = new BridgeBasedBuilder(); - bridgeBasedBuilder.setBridgeDomain(((BridgeBased) interconnection).getBridgeDomain()); - bridgeBasedBuilder - .setBridgedVirtualInterface(((BridgeBased) interconnection).isBridgedVirtualInterface()); - bridgeBasedBuilder.setSplitHorizonGroup(((BridgeBased) interconnection).getSplitHorizonGroup()); - l2Builder.setInterconnection(bridgeBasedBuilder.build()); - } - } - - return Initialized.create(getCfgId(id), l2Builder.build()); - } - - private InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ProxyArpCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ProxyArpCustomizer.java deleted file mode 100644 index e3d6ed0eb..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ProxyArpCustomizer.java +++ /dev/null @@ -1,79 +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.honeycomb.translate.v3po.interfacesstate; - -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.honeycomb.translate.vpp.util.NamingContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArp; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ProxyArpCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class); - private final NamingContext interfaceContext; - - public ProxyArpCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - } - - @Override - public void merge(@Nonnull Builder parentBuilder, - @Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214 - .interfaces.state._interface.ProxyArp readValue) { - - ((VppInterfaceStateAugmentationBuilder) parentBuilder).setProxyArp(readValue); - } - - @Nonnull - @Override - public org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state - ._interface.ProxyArpBuilder getBuilder( - @Nonnull InstanceIdentifier id) { - - return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces - .state._interface.ProxyArpBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull InstanceIdentifier id, - @Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po - .rev161214.interfaces.state._interface.ProxyArpBuilder builder, - @Nonnull ReadContext ctx) throws ReadFailedException { - - //TODO: VPP-225 Implement fully when VPP Proxy ARP read API is available + add initializing - final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - LOG.warn("Reading of ARP data not (yet) supported by VPP API"); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/RewriteCustomizer.java deleted file mode 100644 index da6bf7a10..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/RewriteCustomizer.java +++ /dev/null @@ -1,147 +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.honeycomb.translate.v3po.interfacesstate; - -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Preconditions; -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.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.vpp.util.TagRewriteOperation; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qTagVlanType; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTagBuilder; -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.vpp.vlan.rev161214._802dot1ad; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1q; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.RewriteBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTagsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTagsKey; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Customizer for reading vlan tag-rewrite configuration state form the VPP. - */ -public class RewriteCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer, InterfaceDataTranslator { - - // No initialization necessary since its parent Subinterface L2 customzier sets the entire subtree during - // initialization - - private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class); - private final NamingContext interfaceContext; - - public RewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, - @Nonnull final Rewrite readValue) { - ((L2Builder) parentBuilder).setRewrite(readValue); - } - - @Nonnull - @Override - public RewriteBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new RewriteBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final RewriteBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { - final String subInterfaceName = getSubInterfaceName(id); - LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); - - final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, - interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache(), LOG); - LOG.debug("VPP sub-interface details: {}", iface); - - checkState(iface.subId != 0, "Interface returned by the VPP is not a sub-interface"); - - final TagRewriteOperation operation = TagRewriteOperation.get(iface.vtrOp); - if (TagRewriteOperation.disabled == operation) { - LOG.debug("Tag rewrite operation is disabled for "); - return; - } - - builder.setVlanType(iface.vtrPushDot1Q == 1 - ? _802dot1q.class - : _802dot1ad.class); - - setPushTags(builder, iface); - setPopTags(builder, operation); - } - - private static String getSubInterfaceName(final InstanceIdentifier id) { - return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), - Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier())); - } - - private void setPopTags(final RewriteBuilder builder, final TagRewriteOperation operation) { - final byte numberOfTagsToPop = operation.getPopTags(); - if (numberOfTagsToPop != 0) { - builder.setPopTags(Short.valueOf(numberOfTagsToPop)); - } - } - - private void setPushTags(final RewriteBuilder builder, final SwInterfaceDetails iface) { - final List tags = new ArrayList<>(); - if (iface.vtrTag1 != 0) { - tags.add(buildTag((short) 0, SVlan.class, iface.vtrTag1)); - } - if (iface.vtrTag2 != 0) { - tags.add(buildTag((short) 1, CVlan.class, iface.vtrTag2)); - } - if (tags.size() > 0) { - builder.setPushTags(tags); - } - } - - private PushTags buildTag(final short index, final Class tagType, final int vlanId) { - final PushTagsBuilder tag = new PushTagsBuilder(); - tag.setIndex(index); - tag.setKey(new PushTagsKey(index)); - final Dot1qTagBuilder dtag = new Dot1qTagBuilder(); - dtag.setTagType(tagType); - dtag.setVlanId(new Dot1qVlanId(vlanId)); - tag.setDot1qTag(dtag.build()); - return tag.build(); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceCustomizer.java deleted file mode 100644 index a2efa8c9f..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceCustomizer.java +++ /dev/null @@ -1,264 +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.honeycomb.translate.v3po.interfacesstate; - -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Preconditions; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qTagVlanType; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan; -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.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTagBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubInterfaceStatus; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfacesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.DefaultBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.UntaggedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTaggedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.MatchBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.TagsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagKey; -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; - -/** - * Customizer for reading sub interfaces form the VPP. - */ -public class SubInterfaceCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, ByteDataTranslator, - InterfaceDataTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class); - private static final Dot1qTag.VlanId ANY_VLAN_ID = new Dot1qTag.VlanId(Dot1qTag.VlanId.Enumeration.Any); - private NamingContext interfaceContext; - - public SubInterfaceCustomizer(@Nonnull final FutureJVppCore jvpp, - @Nonnull final NamingContext interfaceContext) { - super(jvpp); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - private static String getSubInterfaceName(final InstanceIdentifier id) { - return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), - Math.toIntExact(id.firstKeyOf(id.getTargetType()).getIdentifier())); - } - - private static Tag buildTag(final short index, final Class tagType, - final Dot1qTag.VlanId vlanId) { - TagBuilder tag = new TagBuilder(); - tag.setIndex(index); - tag.setKey(new TagKey(index)); - final Dot1qTagBuilder dtag = new Dot1qTagBuilder(); - dtag.setTagType(tagType); - dtag.setVlanId(vlanId); - tag.setDot1qTag(dtag.build()); - return tag.build(); - } - - private static Dot1qTag.VlanId buildVlanId(final short vlanId) { - // treat vlanId as unsigned value: - return new Dot1qTag.VlanId(new Dot1qVlanId(0xffff & vlanId)); - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext context) throws ReadFailedException { - // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) - // to fill in the context with initial ifc mapping - final InterfaceKey key = id.firstKeyOf(Interface.class); - final String ifaceName = key.getName(); - final int ifaceId = interfaceContext.getIndex(ifaceName, context.getMappingContext()); - - // TODO HONEYCOMB-189 if we know that full dump was already performed we could use cache - // (checking if getCachedInterfaceDump() returns non empty map is not enough, because - // we could be part of particular iface state read - final SwInterfaceDump request = new SwInterfaceDump(); - request.nameFilter = "".getBytes(); - request.nameFilterValid = 0; - - final CompletableFuture swInterfaceDetailsReplyDumpCompletableFuture = - getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); - final SwInterfaceDetailsReplyDump ifaces = - getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); - - if (null == ifaces || null == ifaces.swInterfaceDetails) { - LOG.warn("Looking for sub-interfaces, but no interfaces found in VPP"); - return Collections.emptyList(); - } - - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - context.getModificationCache() - .put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); - - final List interfacesKeys = ifaces.swInterfaceDetails.stream() - .filter(elt -> elt != null) - // accept only sub-interfaces for current iface: - .filter(elt -> elt.subId != 0 && elt.supSwIfIndex == ifaceId) - .map(details -> new SubInterfaceKey(new Long(details.subId))) - .collect(Collectors.toList()); - - LOG.debug("Sub-interfaces of {} found in VPP: {}", ifaceName, interfacesKeys); - return interfacesKeys; - } - - @Override - public void merge(@Nonnull final Builder builder, - @Nonnull final List readData) { - ((SubInterfacesBuilder) builder).setSubInterface(readData); - } - - @Nonnull - @Override - public SubInterfaceBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new SubInterfaceBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final SubInterfaceBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { - final String subInterfaceName = getSubInterfaceName(id); - LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); - - final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, - interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache(), LOG); - LOG.debug("VPP sub-interface details: {}", iface); - - checkState(iface.subId != 0, "Interface returned by the VPP is not a sub-interface"); - - builder.setIdentifier(Long.valueOf(iface.subId)); - builder.setKey(new SubInterfaceKey(builder.getIdentifier())); - - // sub-interface-base-attributes: - builder.setTags(readTags(iface)); - builder.setMatch(readMatch(iface)); - - // sub-interface-operational-attributes: - builder.setAdminStatus(1 == iface.adminUpDown - ? SubInterfaceStatus.Up - : SubInterfaceStatus.Down); - builder.setOperStatus(1 == iface.linkUpDown - ? SubInterfaceStatus.Up - : SubInterfaceStatus.Down); - builder.setIfIndex(vppIfIndexToYang(iface.swIfIndex)); - if (iface.l2AddressLength == 6) { - builder.setPhysAddress(new PhysAddress(vppPhysAddrToYang(iface.l2Address))); - } - if (0 != iface.linkSpeed) { - builder.setSpeed(vppInterfaceSpeedToYang(iface.linkSpeed)); - } - } - - private Tags readTags(final SwInterfaceDetails iface) { - final TagsBuilder tags = new TagsBuilder(); - final List list = new ArrayList<>(); - if (iface.subNumberOfTags > 0) { - if (iface.subOuterVlanIdAny == 1) { - list.add(buildTag((short) 0, SVlan.class, ANY_VLAN_ID)); - } else { - list.add(buildTag((short) 0, SVlan.class, buildVlanId(iface.subOuterVlanId))); - } - // inner tag (customer tag): - if (iface.subNumberOfTags == 2) { - if (iface.subInnerVlanIdAny == 1) { - list.add(buildTag((short) 1, CVlan.class, ANY_VLAN_ID)); - } else { - list.add(buildTag((short) 1, CVlan.class, buildVlanId(iface.subInnerVlanId))); - } - } - } - tags.setTag(list); - return tags.build(); - } - - private Match readMatch(final SwInterfaceDetails iface) { - final MatchBuilder match = new MatchBuilder(); - if (iface.subDefault == 1) { - match.setMatchType(new DefaultBuilder().build()); - } else if (iface.subNumberOfTags == 0) { - match.setMatchType(new UntaggedBuilder().build()); - } else { - final VlanTaggedBuilder tagged = new VlanTaggedBuilder(); - tagged.setMatchExactTags(byteToBoolean(iface.subExactMatch)); - match.setMatchType( - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.VlanTaggedBuilder() - .setVlanTagged(tagged.build()).build()); - } - return match.build(); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final SubInterface readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder() - .setEnabled(SubInterfaceStatus.Up.equals(readValue.getAdminStatus())) - .setIdentifier(readValue.getIdentifier()) - .setMatch(readValue.getMatch()) - .setTags(readValue.getTags()) - .setVlanType(readValue.getVlanType()) - .build()); - } - - public static InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(SubinterfaceAugmentation.class) - .child(SubInterfaces.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey( - id.firstKeyOf(SubInterface.class).getIdentifier())); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java deleted file mode 100644 index c686d1880..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java +++ /dev/null @@ -1,93 +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.honeycomb.translate.v3po.interfacesstate; - -import static io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils.getSubInterfaceName; - -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.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; -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; - -/** - * Customizer for reading vlan sub interface L2 operational state - */ -public class SubInterfaceL2Customizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class); - private final InterconnectionReadUtils icReadUtils; - - public SubInterfaceL2Customizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext, - @Nonnull final NamingContext bridgeDomainContext) { - super(futureJVppCore); - this.icReadUtils = new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final L2 readValue) { - ((SubInterfaceBuilder) parentBuilder).setL2(readValue); - } - - @Nonnull - @Override - public L2Builder getBuilder(@Nonnull final InstanceIdentifier id) { - return new L2Builder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2Builder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - LOG.debug("Reading attributes for sub-interface L2: {}", id); - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - final String subInterfaceName = getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - - builder.setInterconnection(icReadUtils.readInterconnection(id, subInterfaceName, ctx)); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final L2 readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), readValue); - } - - static InstanceIdentifier getCfgId(final InstanceIdentifier id) { - return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) - .child(L2.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/TapCustomizer.java deleted file mode 100644 index 2c1bdcd43..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/TapCustomizer.java +++ /dev/null @@ -1,143 +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.honeycomb.translate.v3po.interfacesstate; - -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.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; -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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.TapBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class TapCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class); - public static final String DUMPED_TAPS_CONTEXT_KEY = TapCustomizer.class.getName() + "dumpedTapsDuringGetAllIds"; - private NamingContext interfaceContext; - - public TapCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { - super(jvpp); - this.interfaceContext = interfaceContext; - } - - @Override - public void merge(@Nonnull Builder parentBuilder, @Nonnull Tap readValue) { - ((VppInterfaceStateAugmentationBuilder) parentBuilder).setTap(readValue); - } - - @Nonnull - @Override - public TapBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new TapBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final TapBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - - final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap.class, LOG)) { - return; - } - - LOG.debug("Reading attributes for tap interface: {}", key.getName()); - - @SuppressWarnings("unchecked") - Map mappedTaps = - (Map) ctx.getModificationCache().get(DUMPED_TAPS_CONTEXT_KEY); - - if (mappedTaps == null) { - // Full Tap dump has to be performed here, no filter or anything is here to help so at least we cache it - final SwInterfaceTapDump request = new SwInterfaceTapDump(); - final CompletionStage swInterfaceTapDetailsReplyDumpCompletionStage = - getFutureJVpp().swInterfaceTapDump(request); - final SwInterfaceTapDetailsReplyDump reply = - getReplyForRead(swInterfaceTapDetailsReplyDumpCompletionStage.toCompletableFuture(), id); - - if (null == reply || null == reply.swInterfaceTapDetails) { - mappedTaps = Collections.emptyMap(); - } else { - final List swInterfaceTapDetails = reply.swInterfaceTapDetails; - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - mappedTaps = swInterfaceTapDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); - } - - ctx.getModificationCache().put(DUMPED_TAPS_CONTEXT_KEY, mappedTaps); - } - - final SwInterfaceTapDetails swInterfaceTapDetails = mappedTaps.get(index); - LOG.trace("Tap interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceTapDetails); - - builder.setTapName(toString(swInterfaceTapDetails.devName)); - LOG.debug("Tap interface: {}, id: {} attributes read as: {}", key.getName(), index, builder); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final Tap readValue, @Nonnull final ReadContext ctx) { - // The MAC address is set from interface details, those details are retrieved from cache - final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - final SwInterfaceDetails ifcDetails = - InterfaceCustomizer.getCachedInterfaceDump(ctx.getModificationCache()).get(index); - - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.TapBuilder() - .setMac(new PhysAddress(vppPhysAddrToYang(ifcDetails.l2Address))) - .setTapName(readValue.getTapName()) -// tapBuilder.setDeviceInstance(); - .build()); - } - - private InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VhostUserCustomizer.java deleted file mode 100644 index a6d17cf2e..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VhostUserCustomizer.java +++ /dev/null @@ -1,154 +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.honeycomb.translate.v3po.interfacesstate; - -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.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.math.BigInteger; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; -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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUserRole; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUserBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class VhostUserCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { - - public static final String DUMPED_VHOST_USERS_CONTEXT_KEY = - VhostUserCustomizer.class.getName() + "dumpedVhostUsersDuringGetAllIds"; - private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class); - private NamingContext interfaceContext; - - public VhostUserCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { - super(jvpp); - this.interfaceContext = interfaceContext; - } - - @Override - public void merge(@Nonnull Builder parentBuilder, @Nonnull VhostUser readValue) { - ((VppInterfaceStateAugmentationBuilder) parentBuilder).setVhostUser(readValue); - } - - @Nonnull - @Override - public VhostUserBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new VhostUserBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final VhostUserBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - - final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser.class, - LOG)) { - return; - } - - LOG.debug("Reading attributes for vhpost user interface: {}", key.getName()); - - @SuppressWarnings("unchecked") - Map mappedVhostUsers = - (Map) ctx.getModificationCache() - .get(DUMPED_VHOST_USERS_CONTEXT_KEY); - - if (mappedVhostUsers == null) { - // Full VhostUser dump has to be performed here, no filter or anything is here to help so at least we cache it - final SwInterfaceVhostUserDump request = new SwInterfaceVhostUserDump(); - final CompletionStage - swInterfaceVhostUserDetailsReplyDumpCompletionStage = - getFutureJVpp().swInterfaceVhostUserDump(request); - final SwInterfaceVhostUserDetailsReplyDump reply = - getReplyForRead(swInterfaceVhostUserDetailsReplyDumpCompletionStage.toCompletableFuture(), id); - - if (null == reply || null == reply.swInterfaceVhostUserDetails) { - mappedVhostUsers = Collections.emptyMap(); - } else { - final List swInterfaceVhostUserDetails = - reply.swInterfaceVhostUserDetails; - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - mappedVhostUsers = swInterfaceVhostUserDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); - } - - ctx.getModificationCache().put(DUMPED_VHOST_USERS_CONTEXT_KEY, mappedVhostUsers); - } - - // Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping - final SwInterfaceVhostUserDetails swInterfaceVhostUserDetails = mappedVhostUsers.get(index); - LOG.trace("Vhost user interface: {} attributes returned from VPP: {}", key.getName(), - swInterfaceVhostUserDetails); - - builder.setRole(swInterfaceVhostUserDetails.isServer == 1 - ? VhostUserRole.Server - : VhostUserRole.Client); - builder.setFeatures(BigInteger.valueOf(swInterfaceVhostUserDetails.features)); - builder.setNumMemoryRegions((long) swInterfaceVhostUserDetails.numRegions); - builder.setSocket(toString(swInterfaceVhostUserDetails.sockFilename)); - builder.setVirtioNetHdrSize((long) swInterfaceVhostUserDetails.virtioNetHdrSz); - // TODO: map error code to meaningful message after VPP-436 is done - builder.setConnectError(Integer.toString(swInterfaceVhostUserDetails.sockErrno)); - - LOG.debug("Vhost user interface: {}, id: {} attributes read as: {}", key.getName(), index, builder); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final VhostUser readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUserBuilder() - .setRole(readValue.getRole()) - .setSocket(readValue.getSocket()) - .build()); - } - - private InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanCustomizer.java deleted file mode 100644 index 1a1220435..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanCustomizer.java +++ /dev/null @@ -1,162 +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.honeycomb.translate.v3po.interfacesstate; - -import static com.google.common.base.Preconditions.checkState; - -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.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetails; -import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.VxlanTunnelDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanVni; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Vxlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class VxlanCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class); - private final NamingContext interfaceContext; - - public VxlanCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { - super(jvpp); - this.interfaceContext = interfaceContext; - } - - @Override - public void merge(@Nonnull Builder parentBuilder, - @Nonnull Vxlan readValue) { - ((VppInterfaceStateAugmentationBuilder) parentBuilder).setVxlan(readValue); - } - - @Nonnull - @Override - public VxlanBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new VxlanBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final VxlanBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - - final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanTunnel.class, LOG)) { - return; - } - - LOG.debug("Reading attributes for vxlan tunnel: {}", key.getName()); - // Dump just a single - final VxlanTunnelDump request = new VxlanTunnelDump(); - request.swIfIndex = index; - - final CompletionStage swInterfaceVxlanDetailsReplyDumpCompletionStage = - getFutureJVpp().vxlanTunnelDump(request); - final VxlanTunnelDetailsReplyDump reply = - getReplyForRead(swInterfaceVxlanDetailsReplyDumpCompletionStage.toCompletableFuture(), id); - - // VPP keeps vxlan tunnel interfaces even after they were deleted (optimization) - // However there ar no longer any vxlan tunnel specific fields assigned to it and this call - // returns nothing - if (reply == null || reply.vxlanTunnelDetails == null || reply.vxlanTunnelDetails.isEmpty()) { - LOG.debug( - "Vxlan tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + - "after delete", key.getName(), index); - return; - } - - checkState(reply.vxlanTunnelDetails.size() == 1, - "Unexpected number of returned vxlan tunnels: {} for tunnel: {}", reply.vxlanTunnelDetails, - key.getName()); - LOG.trace("Vxlan tunnel: {} attributes returned from VPP: {}", key.getName(), reply); - - final VxlanTunnelDetails swInterfaceVxlanDetails = reply.vxlanTunnelDetails.get(0); - if (swInterfaceVxlanDetails.isIpv6 == 1) { - final Ipv6Address dstIpv6 = - new Ipv6Address(parseAddress(swInterfaceVxlanDetails.dstAddress).getHostAddress()); - builder.setDst(new IpAddress(dstIpv6)); - final Ipv6Address srcIpv6 = - new Ipv6Address(parseAddress(swInterfaceVxlanDetails.srcAddress).getHostAddress()); - builder.setSrc(new IpAddress(srcIpv6)); - } else { - final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.dstAddress, 0, 4); - final Ipv4Address dstIpv4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); - builder.setDst(new IpAddress(dstIpv4)); - final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.srcAddress, 0, 4); - final Ipv4Address srcIpv4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); - builder.setSrc(new IpAddress(srcIpv4)); - } - builder.setEncapVrfId((long) swInterfaceVxlanDetails.encapVrfId); - builder.setVni(new VxlanVni((long) swInterfaceVxlanDetails.vni)); - LOG.debug("Vxlan tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); - } - - @Nonnull - private static InetAddress parseAddress(@Nonnull final byte[] addr) { - try { - return InetAddress.getByAddress(addr); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e); - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final Vxlan readValue, @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanBuilder() - .setDst(readValue.getDst()) - .setSrc(readValue.getSrc()) - .setEncapVrfId(readValue.getEncapVrfId()) - .setVni(new VxlanVni(readValue.getVni())) - .build()); - } - - private InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanGpeCustomizer.java deleted file mode 100644 index 278e23912..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanGpeCustomizer.java +++ /dev/null @@ -1,168 +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.honeycomb.translate.v3po.interfacesstate; - -import static com.google.common.base.Preconditions.checkState; - -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.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetails; -import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeNextProtocol; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeVni; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpe; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpeBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class VxlanGpeCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class); - private NamingContext interfaceContext; - - public VxlanGpeCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { - super(jvpp); - this.interfaceContext = interfaceContext; - } - - @Override - public void merge(@Nonnull Builder parentBuilder, - @Nonnull VxlanGpe readValue) { - ((VppInterfaceStateAugmentationBuilder) parentBuilder).setVxlanGpe(readValue); - } - - @Nonnull - @Override - public VxlanGpeBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new VxlanGpeBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final VxlanGpeBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - - final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanGpeTunnel.class, LOG)) { - return; - } - - LOG.debug("Reading attributes for VxlanGpe tunnel: {}", key.getName()); - // Dump just a single - final VxlanGpeTunnelDump request = new VxlanGpeTunnelDump(); - request.swIfIndex = index; - - final CompletionStage swInterfaceVxlanGpeDetailsReplyDumpCompletionStage = - getFutureJVpp().vxlanGpeTunnelDump(request); - final VxlanGpeTunnelDetailsReplyDump reply = - getReplyForRead(swInterfaceVxlanGpeDetailsReplyDumpCompletionStage.toCompletableFuture(), - id); - - // VPP keeps VxlanGpe tunnel interfaces even after they were deleted (optimization) - // However there are no longer any VxlanGpe tunnel specific fields assigned to it and this call - // returns nothing - if (reply == null || reply.vxlanGpeTunnelDetails == null || reply.vxlanGpeTunnelDetails.isEmpty()) { - LOG.debug( - "VxlanGpe tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + - "after delete", key.getName(), index); - return; - } - - checkState(reply.vxlanGpeTunnelDetails.size() == 1, - "Unexpected number of returned VxlanGpe tunnels: {} for tunnel: {}", reply.vxlanGpeTunnelDetails, - key.getName()); - LOG.trace("VxlanGpe tunnel: {} attributes returned from VPP: {}", key.getName(), reply); - - final VxlanGpeTunnelDetails swInterfaceVxlanGpeDetails = reply.vxlanGpeTunnelDetails.get(0); - if (swInterfaceVxlanGpeDetails.isIpv6 == 1) { - final Ipv6Address remote6 = - new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.remote).getHostAddress()); - builder.setRemote(new IpAddress(remote6)); - final Ipv6Address local6 = - new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.local).getHostAddress()); - builder.setLocal(new IpAddress(local6)); - } else { - final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.remote, 0, 4); - final Ipv4Address remote4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); - builder.setRemote(new IpAddress(remote4)); - final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.local, 0, 4); - final Ipv4Address local4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); - builder.setLocal(new IpAddress(local4)); - } - builder.setVni(new VxlanGpeVni((long) swInterfaceVxlanGpeDetails.vni)); - builder.setNextProtocol(VxlanGpeNextProtocol.forValue(swInterfaceVxlanGpeDetails.protocol)); - builder.setEncapVrfId((long) swInterfaceVxlanGpeDetails.encapVrfId); - builder.setDecapVrfId((long) swInterfaceVxlanGpeDetails.decapVrfId); - LOG.debug("VxlanGpe tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); - } - - @Nonnull - private static InetAddress parseAddress(@Nonnull final byte[] addr) { - try { - return InetAddress.getByAddress(addr); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e); - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final VxlanGpe readValue, @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpeBuilder() - .setLocal(readValue.getLocal()) - .setRemote(readValue.getRemote()) - .setVni(new VxlanGpeVni(readValue.getVni())) - .setNextProtocol(readValue.getNextProtocol()) - .setEncapVrfId(readValue.getEncapVrfId()) - .setDecapVrfId(readValue.getDecapVrfId()) - .build()); - } - - private InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclCustomizer.java deleted file mode 100644 index 6212f724a..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclCustomizer.java +++ /dev/null @@ -1,118 +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.honeycomb.translate.v3po.interfacesstate.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -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.honeycomb.translate.v3po.interfacesstate.InterfaceCustomizer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.IngressBuilder; -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; - -/** - * Customizer for reading ingress ACLs enabled on given interface. - */ -public class AclCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, AclReader, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class); - private final NamingContext interfaceContext; - private final VppClassifierContextManager classifyTableContext; - - public AclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(jvpp); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ingress readValue) { - ((AclBuilder) parentBuilder).setIngress(readValue); - } - - @Nonnull - @Override - public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new IngressBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final IngressBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - LOG.debug("Reading attributes for interface ACL: {}", id); - final InterfaceKey interfaceKey = id.firstKeyOf(Interface.class); - checkArgument(interfaceKey != null, "No parent interface key found"); - - final ClassifyTableByInterface request = new ClassifyTableByInterface(); - request.swIfIndex = interfaceContext.getIndex(interfaceKey.getName(), ctx.getMappingContext()); - - final ClassifyTableByInterfaceReply reply = - getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); - - builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext())); - builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext())); - builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext())); - - if (LOG.isTraceEnabled()) { - LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build()); - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final Ingress readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.IngressBuilder() - .setL2Acl(readValue.getL2Acl()) - .setIp4Acl(readValue.getIp4Acl()) - .setIp6Acl(readValue.getIp6Acl()) - .build()); - } - - private InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclReader.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclReader.java deleted file mode 100644 index a905674e0..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclReader.java +++ /dev/null @@ -1,60 +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.honeycomb.translate.v3po.interfacesstate.acl.ingress; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2AclBuilder; - -interface AclReader { - - @Nonnull - default L2Acl readL2Acl(final int l2TableId, @Nonnull final VppClassifierContextManager classifyTableContext, - @Nonnull final MappingContext mappingContext) { - if (l2TableId == ~0) { - return null; - } - return new L2AclBuilder() - .setClassifyTable(classifyTableContext.getTableName(l2TableId, mappingContext)).build(); - } - - @Nonnull - default Ip4Acl readIp4Acl(final int ip4TableId, @Nonnull final VppClassifierContextManager classifyTableContext, - @Nonnull final MappingContext mappingContext) { - if (ip4TableId == ~0) { - return null; - } - return new Ip4AclBuilder() - .setClassifyTable(classifyTableContext.getTableName(ip4TableId, mappingContext)).build(); - } - - @Nonnull - default Ip6Acl readIp6Acl(final int ip6TableId, @Nonnull final VppClassifierContextManager classifyTableContext, - @Nonnull final MappingContext mappingContext) { - if (ip6TableId == ~0) { - return null; - } - return new Ip6AclBuilder() - .setClassifyTable(classifyTableContext.getTableName(ip6TableId, mappingContext)).build(); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java deleted file mode 100644 index ad6303531..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java +++ /dev/null @@ -1,120 +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.honeycomb.translate.v3po.interfacesstate.acl.ingress; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils.getSubInterfaceName; - -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.honeycomb.translate.v3po.interfacesstate.SubInterfaceCustomizer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder; -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; - -/** - * Customizer for reading ingress ACLs enabled on given sub-interface. - */ -public class SubInterfaceAclCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer, AclReader, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class); - private final NamingContext interfaceContext; - private final VppClassifierContextManager classifyTableContext; - - public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(jvpp); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ingress readValue) { - ((AclBuilder) parentBuilder).setIngress(readValue); - } - - @Nonnull - @Override - public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new IngressBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final IngressBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - LOG.debug("Reading attributes for sub-interface ACL: {}", id); - final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); - checkArgument(parentInterfacekey != null, "No parent interface key found"); - final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - checkArgument(subInterfacekey != null, "No sub-interface key found"); - final String subInterfaceName = - getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - - final ClassifyTableByInterface request = new ClassifyTableByInterface(); - request.swIfIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); - - final ClassifyTableByInterfaceReply reply = - getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); - - builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext())); - builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext())); - builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext())); - - if (LOG.isTraceEnabled()) { - LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build()); - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final Ingress readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), readValue); - } - - static InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) - .child(Acl.class) - .child(Ingress.class); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java deleted file mode 100644 index fb09e3a2e..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java +++ /dev/null @@ -1,166 +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.honeycomb.translate.v3po.interfacesstate.ip; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableSet; -import com.google.common.base.Preconditions; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; -import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; -import io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceCustomizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.params.AddressDumpParams; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.IpAddressDetails; -import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.List; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLengthBuilder; -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; - -/** - * Read customizer for interface Ipv4 addresses. - */ -public class Ipv4AddressCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, Ipv4Reader { - - private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressCustomizer.class); - private static final String CACHE_KEY = Ipv4AddressCustomizer.class.getName(); - - private final NamingContext interfaceContext; - private final DumpCacheManager dumpManager; - - public Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.dumpManager = - new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(createExecutor(futureJVppCore)) - // Key needs to contain interface ID to distinguish dumps between interfaces - .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(Interface.class))) - .build(); - } - - @Override - @Nonnull - public AddressBuilder getBuilder(@Nonnull InstanceIdentifier

id) { - return new AddressBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull InstanceIdentifier
id, @Nonnull AddressBuilder builder, - @Nonnull ReadContext ctx) - throws ReadFailedException { - LOG.debug("Reading attributes for interface address: {}", id); - - final String interfaceName = id.firstKeyOf(Interface.class).getName(); - final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); - final Optional dumpOptional = - dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); - - if (!dumpOptional.isPresent() || dumpOptional.get().ipAddressDetails.isEmpty()) { - return; - } - final Optional ipAddressDetails = - findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); - - if (ipAddressDetails.isPresent()) { - final IpAddressDetails detail = ipAddressDetails.get(); - builder.setIp(arrayToIpv4AddressNoZone(detail.ip)) - .setSubnet( - new PrefixLengthBuilder().setPrefixLength(Short.valueOf(detail.prefixLength)).build()); - - if (LOG.isDebugEnabled()) { - LOG.debug("Attributes for {} interface (id={}) address {} successfully read: {}", - interfaceName, interfaceIndex, id, builder.build()); - } - } - } - - @Override - public List getAllIds(@Nonnull InstanceIdentifier
id, @Nonnull ReadContext ctx) - throws ReadFailedException { - LOG.debug("Reading list of keys for interface addresses: {}", id); - - final String interfaceName = id.firstKeyOf(Interface.class).getName(); - final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); - final Optional dumpOptional = - dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); - - return getAllIpv4AddressIds(dumpOptional, AddressKey::new); - } - - @Override - public void merge(@Nonnull Builder builder, @Nonnull List
readData) { - ((Ipv4Builder) builder).setAddress(readData); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier
id, @Nonnull final Address readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder() - .setIp(readValue.getIp()) - .setSubnet(getSubnet(readValue)) - .build()); - } - - private static Subnet getSubnet(final Address address) { - final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.Subnet - subnet = address.getSubnet(); - - // Only prefix length supported - Preconditions.checkArgument( - subnet instanceof org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLength); - - return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder() - .setPrefixLength( - ((org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLength) subnet) - .getPrefixLength()).build(); - } - - static InstanceIdentifier getCfgId( - final InstanceIdentifier
id) { - return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(Interface1.class) - .child(Ipv4.class) - .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address.class, - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressKey(id.firstKeyOf(Address.class).getIp())); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Customizer.java deleted file mode 100644 index 4c4803fd9..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Customizer.java +++ /dev/null @@ -1,59 +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.honeycomb.translate.v3po.interfacesstate.ip; - -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 javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class Ipv4Customizer extends FutureJVppCustomizer implements ReaderCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class); - - public Ipv4Customizer(@Nonnull final FutureJVppCore futureJVppCore) { - super(futureJVppCore); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ipv4 readValue) { - ((Interface2Builder) parentBuilder).setIpv4(readValue); - } - - @Nonnull - @Override - public Ipv4Builder getBuilder(@Nonnull final InstanceIdentifier id) { - return new Ipv4Builder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ipv4Builder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - LOG.debug("Reading Ipv4 leaves (mtu, forwarding) is not supported by VPP API"); - } - -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java deleted file mode 100644 index afc22591d..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java +++ /dev/null @@ -1,73 +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.honeycomb.translate.v3po.interfacesstate.ip; - -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -import java.util.List; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborKey; -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; - -/** - * Operational data read operation customizer for {@link Neighbor}
- * Currently not supported in jvpp, so this is only dummy implementation
- */ -public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); - - public Ipv4NeighbourCustomizer(FutureJVppCore futureJVppCore) { - super(futureJVppCore); - } - - @Override - public NeighborBuilder getBuilder(InstanceIdentifier id) { - return new NeighborBuilder(); - } - - @Override - public void readCurrentAttributes(InstanceIdentifier id, NeighborBuilder builder, ReadContext ctx) - throws ReadFailedException { - //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first + implement init - LOG.warn("Operation not supported"); - } - - @Override - public List getAllIds(InstanceIdentifier id, ReadContext context) - throws ReadFailedException { - //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first - LOG.warn("Operation not supported,returning empty List"); - return Collections.emptyList(); - } - - @Override - public void merge(Builder builder, List readData) { - ((Ipv4Builder) builder).setNeighbor(readData); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Reader.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Reader.java deleted file mode 100644 index a5d13bb98..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Reader.java +++ /dev/null @@ -1,84 +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.honeycomb.translate.v3po.interfacesstate.ip; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; -import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.params.AddressDumpParams; -import io.fd.honeycomb.translate.vpp.util.Ipv4Translator; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.vpp.jvpp.core.dto.IpAddressDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -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.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yangtools.yang.binding.Identifier; -import io.fd.vpp.jvpp.core.dto.IpAddressDetails; -import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; - -/** - * Utility class providing Ipv4 read support. - */ -interface Ipv4Reader extends Ipv4Translator, JvppReplyConsumer { - - @Nonnull - default List getAllIpv4AddressIds( - final Optional dumpOptional, - @Nonnull final Function keyConstructor) { - if (dumpOptional.isPresent() && dumpOptional.get().ipAddressDetails != null) { - return dumpOptional.get().ipAddressDetails.stream() - .map(detail -> keyConstructor.apply(arrayToIpv4AddressNoZone(detail.ip))) - .collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - } - - default Optional findIpAddressDetailsByIp( - final Optional dump, - @Nonnull final Ipv4AddressNoZone ip) { - checkNotNull(ip, "ip address should not be null"); - - if (dump.isPresent() && dump.get().ipAddressDetails != null) { - final List details = dump.get().ipAddressDetails; - - return Optional.of(details.stream() - .filter(singleDetail -> ip.equals(arrayToIpv4AddressNoZone(singleDetail.ip))) - .collect(RWUtils.singleItemCollector())); - } - return Optional.absent(); - } - - default EntityDumpExecutor createExecutor( - @Nonnull final FutureJVppCore vppApi) { - return (identifier, params) -> { - checkNotNull(params, "Address dump params cannot be null"); - - final IpAddressDump dumpRequest = new IpAddressDump(); - dumpRequest.isIpv6 = booleanToByte(params.isIpv6()); - dumpRequest.swIfIndex = params.getInterfaceIndex(); - - return getReplyForRead(vppApi.ipAddressDump(dumpRequest).toCompletableFuture(), identifier); - }; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv6Customizer.java deleted file mode 100644 index a2e7bcc10..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv6Customizer.java +++ /dev/null @@ -1,66 +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.honeycomb.translate.v3po.interfacesstate.ip; - -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.honeycomb.translate.vpp.util.NamingContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6Builder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -public class Ipv6Customizer extends FutureJVppCustomizer implements ReaderCustomizer { - - private final NamingContext interfaceContext; - - public Ipv6Customizer(@Nonnull final FutureJVppCore futureJVppCore, final NamingContext interfaceContext) { - super(futureJVppCore); - this.interfaceContext = interfaceContext; - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Ipv6 readValue) { - ((Interface2Builder) parentBuilder).setIpv6(readValue); - } - - @Nonnull - @Override - public Ipv6Builder getBuilder(@Nonnull final InstanceIdentifier id) { - return new Ipv6Builder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Ipv6Builder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { - // TODO HONEYCOMB-102 implement + init -// final IpAddressDump dumpRequest = new IpAddressDump(); -// dumpRequest.isIpv6 = 1; -// dumpRequest.swIfIndex = interfaceContext.getIndex(id.firstKeyOf(Interface.class).getName(), -// ctx.getMappingContext()); -// final CompletionStage addressDumpFuture = getFutureJVpp(). -// ipAddressDump(dumpRequest); -// final IpAddressDetailsReplyDump reply = TranslateUtils.getReply(addressDumpFuture.toCompletableFuture()); - } - -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java deleted file mode 100644 index e18de5581..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java +++ /dev/null @@ -1,143 +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.honeycomb.translate.v3po.interfacesstate.ip; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableSet; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; -import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; -import io.fd.honeycomb.translate.v3po.interfacesstate.SubInterfaceCustomizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.params.AddressDumpParams; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; -import io.fd.vpp.jvpp.core.dto.IpAddressDetails; -import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.List; -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.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder; -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; - -/** - * Read customizer for sub-interface Ipv4 addresses. - */ -public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, Ipv4Reader { - - private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class); - - private final NamingContext interfaceContext; - private final DumpCacheManager dumpManager; - - public SubInterfaceIpv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(createExecutor(futureJVppCore)) - //same as with ipv4 addresses for interfaces, these must have cache scope of their parent sub-interface - .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(SubInterface.class))) - .build(); - } - - @Override - @Nonnull - public AddressBuilder getBuilder(@Nonnull InstanceIdentifier
id) { - return new AddressBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull InstanceIdentifier
id, @Nonnull AddressBuilder builder, - @Nonnull ReadContext ctx) - throws ReadFailedException { - LOG.debug("Reading attributes for sub-interface address: {}", id); - - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); - final Optional dumpOptional = dumpManager - .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); - - final Optional ipAddressDetails = - findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); - - if (ipAddressDetails.isPresent()) { - final IpAddressDetails detail = ipAddressDetails.get(); - builder.setIp(arrayToIpv4AddressNoZone(detail.ip)); - builder.setSubnet(new PrefixLengthBuilder().setPrefixLength(Short.valueOf(detail.prefixLength)).build()); - - if (LOG.isDebugEnabled()) { - LOG.debug("Attributes for {} sub-interface (id={}) address {} successfully read: {}", - subInterfaceName, subInterfaceIndex, id, builder.build()); - } - } - } - - @Override - public List getAllIds(@Nonnull InstanceIdentifier
id, @Nonnull ReadContext ctx) - throws ReadFailedException { - LOG.debug("Reading list of keys for sub-interface addresses: {}", id); - - final String subInterfaceName = getSubInterfaceName(id); - final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); - final Optional dumpOptional = dumpManager - .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); - - return getAllIpv4AddressIds(dumpOptional, AddressKey::new); - } - - @Override - public void merge(@Nonnull Builder builder, @Nonnull List
readData) { - ((Ipv4Builder) builder).setAddress(readData); - } - - private static String getSubInterfaceName(@Nonnull final InstanceIdentifier
id) { - return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), - Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier())); - } - - @Override - public Initialized
init( - @Nonnull final InstanceIdentifier
id, @Nonnull final Address readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), readValue); - } - - private InstanceIdentifier
getCfgId(final InstanceIdentifier
id) { - return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) - .child(Ipv4.class) - .child(Address.class, new AddressKey(id.firstKeyOf(Address.class))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java deleted file mode 100644 index c5ada2d38..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java +++ /dev/null @@ -1,44 +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.honeycomb.translate.v3po.interfacesstate.ip.dump.params; - -public class AddressDumpParams { - - private final int interfaceIndex; - private final boolean isIpv6; - - public AddressDumpParams(final int interfaceIndex, final boolean isIpv6) { - this.interfaceIndex = interfaceIndex; - this.isIpv6 = isIpv6; - } - - public int getInterfaceIndex() { - return interfaceIndex; - } - - public boolean isIpv6() { - return isIpv6; - } - - @Override - public String toString() { - return "AddressDumpParams{" + - "interfaceIndex=" + interfaceIndex + - ", isIpv6=" + isIpv6 + - '}'; - } -} 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 deleted file mode 100644 index 69b8c95bf..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java +++ /dev/null @@ -1,57 +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.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.rev161214.PbbRewriteStateInterfaceAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.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 + init - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, - @Nonnull final PbbRewriteState readValue) { - ((PbbRewriteStateInterfaceAugmentationBuilder) parentBuilder).setPbbRewriteState(readValue); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/notification/InterfaceChangeNotificationProducer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/notification/InterfaceChangeNotificationProducer.java deleted file mode 100644 index 115727ad0..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/notification/InterfaceChangeNotificationProducer.java +++ /dev/null @@ -1,163 +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.honeycomb.translate.v3po.notification; - -import com.google.common.base.Optional; -import com.google.common.collect.Lists; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.notification.ManagedNotificationProducer; -import io.fd.honeycomb.notification.NotificationCollector; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeoutException; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.concurrent.NotThreadSafe; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceDeleted; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceDeletedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceNameOrIndex; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStateChange; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStateChangeBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStatus; -import org.opendaylight.yangtools.yang.binding.Notification; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsNotification; -import io.fd.vpp.jvpp.core.dto.WantInterfaceEvents; -import io.fd.vpp.jvpp.core.dto.WantInterfaceEventsReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Notification producer for interface events. It starts interface notification stream and for every - * received notification, it transforms it into its BA equivalent and pushes into HC's notification collector. - */ -@NotThreadSafe -public final class InterfaceChangeNotificationProducer implements ManagedNotificationProducer, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(InterfaceChangeNotificationProducer.class); - - private final FutureJVppCore jvpp; - private final NamingContext interfaceContext; - private final MappingContext mappingContext; - @Nullable - private AutoCloseable notificationListenerReg; - - @Inject - public InterfaceChangeNotificationProducer(@Nonnull final FutureJVppCore jvpp, - @Named("interface-context") @Nonnull final NamingContext interfaceContext, - @Named("honeycomb-context") @Nonnull final MappingContext mappingContext) { - this.jvpp = jvpp; - this.interfaceContext = interfaceContext; - this.mappingContext = mappingContext; - } - - @Override - public void start(final NotificationCollector collector) { - LOG.trace("Starting interface notifications"); - enableDisableIfcNotifications(1); - LOG.debug("Interface notifications started successfully"); - notificationListenerReg = jvpp.getNotificationRegistry().registerSwInterfaceSetFlagsNotificationCallback( - swInterfaceSetFlagsNotification -> { - LOG.trace("Interface notification received: {}", swInterfaceSetFlagsNotification); - // TODO HONEYCOMB-166 this should be lazy - collector.onNotification(transformNotification(swInterfaceSetFlagsNotification)); - } - ); - } - - private Notification transformNotification(final SwInterfaceSetFlagsNotification swInterfaceSetFlagsNotification) { - if (swInterfaceSetFlagsNotification.deleted == 1) { - return new InterfaceDeletedBuilder().setName(getIfcName(swInterfaceSetFlagsNotification)).build(); - } else { - return new InterfaceStateChangeBuilder() - .setName(getIfcName(swInterfaceSetFlagsNotification)) - .setAdminStatus(swInterfaceSetFlagsNotification.adminUpDown == 1 - ? InterfaceStatus.Up - : InterfaceStatus.Down) - .setOperStatus(swInterfaceSetFlagsNotification.linkUpDown == 1 - ? InterfaceStatus.Up - : InterfaceStatus.Down) - .build(); - } - } - - /** - * Get mapped name for the interface. Best effort only! The mapping might not yet be stored in context - * data tree (write transaction is still in progress and context changes have not been committed yet, or - * VPP sends the notification before it returns create request(that would store mapping)). - *

- * In case mapping is not available, index is used as name. - */ - private InterfaceNameOrIndex getIfcName(final SwInterfaceSetFlagsNotification swInterfaceSetFlagsNotification) { - final Optional optionalName = - interfaceContext.getNameIfPresent(swInterfaceSetFlagsNotification.swIfIndex, mappingContext); - return optionalName.isPresent() - ? new InterfaceNameOrIndex(optionalName.get()) - : new InterfaceNameOrIndex((long) swInterfaceSetFlagsNotification.swIfIndex); - } - - @Override - public void stop() { - LOG.trace("Stopping interface notifications"); - enableDisableIfcNotifications(0); - LOG.debug("Interface notifications stopped successfully"); - try { - if (notificationListenerReg != null) { - notificationListenerReg.close(); - } - } catch (Exception e) { - LOG.warn("Unable to properly close notification registration: {}", notificationListenerReg, e); - } - } - - private void enableDisableIfcNotifications(int enableDisable) { - final WantInterfaceEvents wantInterfaceEvents = new WantInterfaceEvents(); - wantInterfaceEvents.pid = 1; - wantInterfaceEvents.enableDisable = enableDisable; - final CompletionStage wantInterfaceEventsReplyCompletionStage; - try { - wantInterfaceEventsReplyCompletionStage = jvpp.wantInterfaceEvents(wantInterfaceEvents); - getReply(wantInterfaceEventsReplyCompletionStage.toCompletableFuture()); - } catch (VppBaseCallException | TimeoutException e) { - LOG.warn("Unable to {} interface notifications", enableDisable == 1 - ? "enable" - : "disable", e); - throw new IllegalStateException("Unable to control interface notifications", e); - } - } - - @Nonnull - @Override - public Collection> getNotificationTypes() { - final ArrayList> classes = Lists.newArrayList(); - classes.add(InterfaceStateChange.class); - classes.add(InterfaceDeleted.class); - return classes; - } - - @Override - public void close() throws Exception { - LOG.trace("Closing interface notifications producer"); - stop(); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/ArpTerminationTableEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/ArpTerminationTableEntryCustomizer.java deleted file mode 100644 index bd9466628..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/ArpTerminationTableEntryCustomizer.java +++ /dev/null @@ -1,118 +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.honeycomb.translate.v3po.vpp; - -import com.google.common.base.Preconditions; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.AddressTranslator; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.BdIpMacAddDel; -import io.fd.vpp.jvpp.core.dto.BdIpMacAddDelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer Customizer responsible for ARP termination table management.
Sends {@code bd_ip_mac_add_del} message to - * VPP.
Equivalent of invoking {@code vppctl set bridge-domain arp term} command. - */ -public class ArpTerminationTableEntryCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, ByteDataTranslator, - AddressTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ArpTerminationTableEntryCustomizer.class); - - private final NamingContext bdContext; - - public ArpTerminationTableEntryCustomizer(@Nonnull final FutureJVppCore futureJvpp, - @Nonnull final NamingContext bdContext) { - super(futureJvpp); - this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ArpTerminationTableEntry dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Creating ARP termination table entry: {} {}", id, dataAfter); - bdIpMacAddDel(id, dataAfter, writeContext, true); - LOG.debug("L2 ARP termination table entry created successfully: {} {}", id, dataAfter); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ArpTerminationTableEntry dataBefore, - @Nonnull final ArpTerminationTableEntry dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - throw new UnsupportedOperationException( - "ARP termination table entry update is not supported. It has to be deleted and then created."); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ArpTerminationTableEntry dataBefore, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Deleting ARP termination table entry entry: {} {}", id, dataBefore); - bdIpMacAddDel(id, dataBefore, writeContext, false); - LOG.debug("ARP termination table entry deleted successfully: {} {}", id, dataBefore); - } - - private void bdIpMacAddDel(@Nonnull final InstanceIdentifier id, - @Nonnull final ArpTerminationTableEntry entry, - final WriteContext writeContext, boolean isAdd) throws WriteFailedException { - final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); - final int bdId = bdContext.getIndex(bdName, writeContext.getMappingContext()); - - final BdIpMacAddDel request = createRequest(entry, bdId, isAdd); - LOG.debug("Sending l2FibAddDel request: {}", request); - final CompletionStage replyCompletionStage = - getFutureJVpp().bdIpMacAddDel(request); - - getReplyForWrite(replyCompletionStage.toCompletableFuture(), id); - } - - private BdIpMacAddDel createRequest(final ArpTerminationTableEntry entry, final int bdId, boolean isAdd) { - final BdIpMacAddDel request = new BdIpMacAddDel(); - request.bdId = bdId; - request.isAdd = booleanToByte(isAdd); - request.macAddress = parseMac(entry.getPhysAddress().getValue()); - - final IpAddress ipAddress = entry.getIpAddress(); - if (ipAddress.getIpv6Address() != null) { - // FIXME: HONEYCOMB-187 vpp does not support ipv6 in arp-termination table (based on analysis of l2_bd.c) - throw new UnsupportedOperationException("IPv6 address for ARP termination table is not supported yet"); - } - - request.ipAddress = ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(ipAddress.getIpv4Address())); - return request; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/BridgeDomainCustomizer.java deleted file mode 100644 index a95c18e5e..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/BridgeDomainCustomizer.java +++ /dev/null @@ -1,137 +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.honeycomb.translate.v3po.vpp; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Preconditions; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -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.core.dto.BridgeDomainAddDel; -import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import javax.annotation.Nonnull; -import javax.annotation.concurrent.GuardedBy; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class BridgeDomainCustomizer - extends FutureJVppCustomizer - implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); - - private static final byte ADD_OR_UPDATE_BD = (byte) 1; - private final NamingContext bdContext; - @GuardedBy("this") - private int bridgeDomainIndexCounter = 1; - - public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext bdContext) { - super(futureJVppCore); - this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); - } - - private BridgeDomainAddDelReply addOrUpdateBridgeDomain(@Nonnull final InstanceIdentifier id, - final int bdId, @Nonnull final BridgeDomain bd) - throws WriteFailedException { - final BridgeDomainAddDelReply reply; - final BridgeDomainAddDel request = new BridgeDomainAddDel(); - request.bdId = bdId; - request.flood = booleanToByte(bd.isFlood()); - request.forward = booleanToByte(bd.isForward()); - request.learn = booleanToByte(bd.isLearn()); - request.uuFlood = booleanToByte(bd.isUnknownUnicastFlood()); - request.arpTerm = booleanToByte(bd.isArpTermination()); - request.isAdd = ADD_OR_UPDATE_BD; - - reply = getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); - LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId); - return reply; - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain dataBefore, - @Nonnull final WriteContext ctx) - throws WriteFailedException { - LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx); - final String bdName = dataBefore.getName(); - - // Invoke 1. check index, 2. increase index 3. create ND 4. store mapping in a synchronized block to prevent - // race conditions in case of concurrent invocation - synchronized (this) { - int index; - if (bdContext.containsIndex(bdName, ctx.getMappingContext())) { - index = bdContext.getIndex(bdName, ctx.getMappingContext()); - } else { - // Critical section due to bridgeDomainIndexCounter read and write access - // TODO HONEYCOMB-199 move this "get next available index" into naming context or an adapter - // or a dedicated object - - // Use counter to assign bridge domain index, but still check naming context if it's not taken there - while (bdContext.containsName(bridgeDomainIndexCounter, ctx.getMappingContext())) { - bridgeDomainIndexCounter++; - } - index = bridgeDomainIndexCounter; - } - addOrUpdateBridgeDomain(id, index, dataBefore); - bdContext.addName(index, bdName, ctx.getMappingContext()); - } - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain dataBefore, - @Nonnull final WriteContext ctx) - throws WriteFailedException { - LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx); - final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); - int bdId = bdContext.getIndex(bdName, ctx.getMappingContext()); - - final BridgeDomainAddDel request = new BridgeDomainAddDel(); - request.bdId = bdId; - - getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); - LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter, - @Nonnull final WriteContext ctx) - throws WriteFailedException { - LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter, - ctx); - - final String bdName = checkNotNull(dataAfter.getName()); - checkArgument(bdName.equals(dataBefore.getName()), - "BridgeDomain name changed. It should be deleted and then created."); - - addOrUpdateBridgeDomain(id, bdContext.getIndex(bdName, ctx.getMappingContext()), dataAfter); - } - -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/L2FibEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/L2FibEntryCustomizer.java deleted file mode 100644 index f37d5dd45..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vpp/L2FibEntryCustomizer.java +++ /dev/null @@ -1,129 +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.honeycomb.translate.v3po.vpp; - -import com.google.common.base.Preconditions; -import com.google.common.primitives.Longs; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -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.core.dto.L2FibAddDel; -import io.fd.vpp.jvpp.core.dto.L2FibAddDelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer Customizer responsible for L2 FIB create/delete operations.
Sends {@code l2_fib_add_del} message to - * VPP.
Equivalent of invoking {@code vppctl l2fib add/del} command. - */ -public class L2FibEntryCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, ByteDataTranslator, MacTranslator, - JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); - - private final NamingContext bdContext; - private final NamingContext interfaceContext; - - public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntry dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - LOG.debug("Creating L2 FIB entry: {} {}", id, dataAfter); - l2FibAddDel(id, dataAfter, writeContext, true); - LOG.debug("L2 FIB entry created successfully: {} {}", id, dataAfter); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntry dataBefore, @Nonnull final L2FibEntry dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - throw new UnsupportedOperationException( - "L2 FIB entry update is not supported. It has to be deleted and then created."); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntry dataBefore, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - LOG.debug("Deleting L2 FIB entry: {} {}", id, dataBefore); - l2FibAddDel(id, dataBefore, writeContext, false); - LOG.debug("L2 FIB entry deleted successfully: {} {}", id, dataBefore); - } - - private void l2FibAddDel(@Nonnull final InstanceIdentifier id, @Nonnull final L2FibEntry entry, - final WriteContext writeContext, boolean isAdd) throws WriteFailedException { - final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); - final int bdId = bdContext.getIndex(bdName, writeContext.getMappingContext()); - - int swIfIndex = -1; - final String swIfName = entry.getOutgoingInterface(); - if (swIfName != null) { - swIfIndex = interfaceContext.getIndex(swIfName, writeContext.getMappingContext()); - } - - final L2FibAddDel l2FibRequest = createL2FibRequest(entry, bdId, swIfIndex, isAdd); - LOG.debug("Sending l2FibAddDel request: {}", l2FibRequest); - final CompletionStage l2FibAddDelReplyCompletionStage = - getFutureJVpp().l2FibAddDel(l2FibRequest); - - getReplyForWrite(l2FibAddDelReplyCompletionStage.toCompletableFuture(), id); - } - - private L2FibAddDel createL2FibRequest(final L2FibEntry entry, final int bdId, final int swIfIndex, boolean isAdd) { - final L2FibAddDel request = new L2FibAddDel(); - request.mac = macToLong(entry.getPhysAddress().getValue()); - request.bdId = bdId; - request.swIfIndex = swIfIndex; - request.isAdd = booleanToByte(isAdd); - if (isAdd) { - request.staticMac = booleanToByte(entry.isStaticConfig()); - request.filterMac = booleanToByte(L2FibFilter.class == entry.getAction()); - } - return request; - } - - // mac address is string of the form: 11:22:33:44:55:66 - // but VPP expects long value in the format 11:22:33:44:55:66:XX:XX - private long macToLong(final String macAddress) { - final byte[] mac = parseMac(macAddress); - return Longs.fromBytes(mac[0], mac[1], mac[2], mac[3], - mac[4], mac[5], (byte) 0, (byte) 0); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionReader.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionReader.java deleted file mode 100644 index 9f4cd7e77..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionReader.java +++ /dev/null @@ -1,207 +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.honeycomb.translate.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedInts; -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.ListReaderCustomizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDetails; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.xml.bind.DatatypeConverter; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; -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; - -/** - * Reader customizer responsible for classify session read.
to VPP.
Equivalent to invoking {@code vppctl show - * class table verbose} command. - */ -public class ClassifySessionReader extends FutureJVppCustomizer - implements ListReaderCustomizer, - InterfaceDataTranslator, VppNodeReader, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionReader.class); - static final String CACHE_KEY = ClassifySessionReader.class.getName(); - - private final VppClassifierContextManager classifyTableContext; - - public ClassifySessionReader(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(futureJVppCore); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void merge(@Nonnull final Builder builder, - @Nonnull final List readData) { - ((ClassifyTableBuilder) builder).setClassifySession(readData); - } - - @Nonnull - @Override - public ClassifySessionBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new ClassifySessionBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySessionBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { - LOG.debug("Reading attributes for classify session: {}", id); - - final ClassifySessionKey key = id.firstKeyOf(ClassifySession.class); - checkArgument(key != null, "could not find ClassifySession key in {}", id); - - final ClassifySessionDetailsReplyDump classifySessionDump = dumpClassifySessions(id, ctx); - final byte[] match = DatatypeConverter.parseHexBinary(key.getMatch().getValue().replace(":", "")); - final Optional classifySession = - findClassifySessionDetailsByMatch(classifySessionDump, match); - - if (classifySession.isPresent()) { - final ClassifySessionDetails detail = classifySession.get(); - builder.setHitNext( - readVppNode(detail.tableId, detail.hitNextIndex, classifyTableContext, ctx.getMappingContext(), LOG) - .get()); - if (detail.opaqueIndex != ~0) { - // value is specified: - builder.setOpaqueIndex(readOpaqueIndex(detail.tableId, detail.opaqueIndex, ctx.getMappingContext())); - } - builder.setAdvance(detail.advance); - builder.setMatch(key.getMatch()); - - if (LOG.isTraceEnabled()) { - LOG.trace("Attributes for classify session {} successfully read: {}", id, builder.build()); - } - } - } - - private OpaqueIndex readOpaqueIndex(final int tableIndex, final int opaqueIndex, final MappingContext ctx) { - // We first try to map the value to a vpp node, if that fails, simply wrap the u32 value - // TODO: HONEYCOMB-118 the approach might fail if the opaqueIndex contains small value that collides - // with some of the adjacent nodes - - final Optional node = readVppNode(tableIndex, opaqueIndex, classifyTableContext, ctx, LOG); - if (node.isPresent()) { - return new OpaqueIndex(node.get()); - } else { - return new OpaqueIndex(UnsignedInts.toLong(opaqueIndex)); - } - } - - @Nullable - private ClassifySessionDetailsReplyDump dumpClassifySessions(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext ctx) - throws ReadFailedException { - final ClassifyTableKey tableKey = id.firstKeyOf(ClassifyTable.class); - checkArgument(tableKey != null, "could not find ClassifyTable key in {}", id); - - final String cacheKey = CACHE_KEY + tableKey; - - ClassifySessionDetailsReplyDump classifySessionDump = - (ClassifySessionDetailsReplyDump) ctx.getModificationCache().get(cacheKey); - if (classifySessionDump != null) { - LOG.debug("Classify sessions is present in cache: {}", cacheKey); - return classifySessionDump; - } - - final String tableName = tableKey.getName(); - checkState(classifyTableContext.containsTable(tableName, ctx.getMappingContext()), - "Reading classify sessions for table {}, but table index could not be found in the classify table context", - tableName); - final int tableId = classifyTableContext.getTableIndex(tableName, ctx.getMappingContext()); - LOG.debug("Dumping classify sessions for classify table id={}", tableId); - - - final ClassifySessionDump dumpRequest = new ClassifySessionDump(); - dumpRequest.tableId = tableId; - final int timeOut = 30; // there can be many session with current ietf-acl implementation (could be probably - // removed after fixing HONEYCOMB-247) - classifySessionDump = - getReplyForRead(getFutureJVpp().classifySessionDump(dumpRequest).toCompletableFuture(), id, timeOut); - - if (classifySessionDump != null) { - // update the cache: - ctx.getModificationCache().put(cacheKey, classifySessionDump); - } - - return classifySessionDump; - } - - private static Optional findClassifySessionDetailsByMatch( - @Nullable final ClassifySessionDetailsReplyDump classifySessionDump, @Nonnull final byte[] match) { - if (classifySessionDump != null && classifySessionDump.classifySessionDetails != null) { - final List details = classifySessionDump.classifySessionDetails; - final List filteredSessions = details.stream() - .filter(singleDetail -> Arrays.equals(singleDetail.match, match)).collect(Collectors.toList()); - if (filteredSessions.isEmpty()) { - return Optional.absent(); - } else if (filteredSessions.size() == 1) { - return Optional.of(filteredSessions.get(0)); - } else { - throw new IllegalStateException(String.format( - "Found %d classify sessions witch given match. Single session expected.", - filteredSessions.size())); - } - } - return Optional.absent(); - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext ctx) throws ReadFailedException { - LOG.debug("Reading list of keys for classify sessions: {}", id); - - final ClassifySessionDetailsReplyDump classifySessionDump = dumpClassifySessions(id, ctx); - if (classifySessionDump != null && classifySessionDump.classifySessionDetails != null) { - return classifySessionDump.classifySessionDetails.stream() - .map(detail -> new ClassifySessionKey(new HexString(printHexBinary(detail.match)))) - .collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionWriter.java deleted file mode 100644 index 996e76eca..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionWriter.java +++ /dev/null @@ -1,165 +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.honeycomb.translate.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.xml.bind.DatatypeConverter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer customizer responsible for classify session create/delete.
Sends {@code classify_add_del_session} message - * to VPP.
Equivalent to invoking {@code vppctl classify table} command. - */ -public class ClassifySessionWriter extends VppNodeWriter - implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionWriter.class); - private final VppClassifierContextManager classifyTableContext; - - public ClassifySessionWriter(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(futureJVppCore); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySession dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Creating classify session: iid={} dataAfter={}", id, dataAfter); - try { - classifyAddDelSession(true, id, dataAfter, writeContext); - LOG.debug("Successfully created classify session: iid={} dataAfter={}", id, dataAfter); - } catch (VppBaseCallException e) { - throw new WriteFailedException.CreateFailedException(id, dataAfter, e); - } - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySession dataBefore, - @Nonnull final ClassifySession dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - throw new UnsupportedOperationException("Classify session update is not supported"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySession dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Removing classify session: iid={} dataBefore={}", id, dataBefore); - try { - classifyAddDelSession(false, id, dataBefore, writeContext); - LOG.debug("Successfully removed classify session: iid={} dataBefore={}", id, dataBefore); - } catch (VppBaseCallException e) { - throw new WriteFailedException.DeleteFailedException(id, e); - } - } - - private void classifyAddDelSession(final boolean isAdd, @Nonnull final InstanceIdentifier id, - @Nonnull final ClassifySession classifySession, - @Nonnull final WriteContext writeContext) - throws VppBaseCallException, WriteFailedException { - final ClassifyTableKey tableKey = id.firstKeyOf(ClassifyTable.class); - checkArgument(tableKey != null, "could not find classify table key in {}", id); - - final String tableName = tableKey.getName(); - checkState(classifyTableContext.containsTable(tableName, writeContext.getMappingContext()), - "Could not find classify table index for {} in the classify table context", tableName); - final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); - - final ClassifyTable classifyTable = - getClassifyTable(writeContext, id.firstIdentifierOf(ClassifyTable.class), isAdd); - final int hitNextIndex = getNodeIndex(classifySession.getHitNext(), classifyTable, classifyTableContext, - writeContext.getMappingContext(), id); - final int opaqueIndex = - getOpaqueIndex(classifySession.getOpaqueIndex(), classifyTable, writeContext.getMappingContext(), id); - - final CompletionStage createClassifyTableReplyCompletionStage = getFutureJVpp() - .classifyAddDelSession( - getClassifyAddDelSessionRequest(isAdd, classifySession, tableIndex, hitNextIndex, opaqueIndex)); - - getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); - } - - private ClassifyTable getClassifyTable(final WriteContext writeContext, - @Nonnull final InstanceIdentifier id, - final boolean isAdd) { - final Optional classifyTable; - if (isAdd) { - classifyTable = writeContext.readAfter(id); - } else { - classifyTable = writeContext.readBefore(id); - } - return classifyTable.get(); - } - - private ClassifyAddDelSession getClassifyAddDelSessionRequest(final boolean isAdd, - @Nonnull final ClassifySession classifySession, - final int tableIndex, - final int hitNextIndex, - final int opaqueIndex) { - ClassifyAddDelSession request = new ClassifyAddDelSession(); - request.isAdd = booleanToByte(isAdd); - request.tableIndex = tableIndex; - request.hitNextIndex = hitNextIndex; - request.opaqueIndex = opaqueIndex; - - // default 0: - request.advance = classifySession.getAdvance(); - - request.match = DatatypeConverter.parseHexBinary(classifySession.getMatch().getValue().replace(":", "")); - return request; - } - - private int getOpaqueIndex(@Nullable final OpaqueIndex opaqueIndex, final ClassifyTable classifyTable, - final MappingContext ctx, final InstanceIdentifier id) - throws VppBaseCallException, WriteFailedException { - if (opaqueIndex == null) { - return ~0; // value not specified - } - if (opaqueIndex.getUint32() != null) { - return opaqueIndex.getUint32().intValue(); - } else { - return getNodeIndex(opaqueIndex.getVppNode(), classifyTable, classifyTableContext, ctx, id); - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableReader.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableReader.java deleted file mode 100644 index 745168635..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableReader.java +++ /dev/null @@ -1,171 +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.honeycomb.translate.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedInts; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceDataTranslator; -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.vpp.jvpp.core.dto.ClassifyTableIds; -import io.fd.vpp.jvpp.core.dto.ClassifyTableIdsReply; -import io.fd.vpp.jvpp.core.dto.ClassifyTableInfo; -import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Arrays; -import java.util.Collections; -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.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; -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; - -/** - * Reader customizer responsible for classify table read.
to VPP.
Equivalent to invoking {@code vppctl show - * class table} command. - */ -public class ClassifyTableReader extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, VppNodeReader, - MacTranslator, InterfaceDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableReader.class); - private final VppClassifierContextManager classifyTableContext; - - public ClassifyTableReader(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(futureJVppCore); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - - @Override - public void merge(@Nonnull final Builder builder, - @Nonnull final List readData) { - ((VppClassifierStateBuilder) builder).setClassifyTable(readData); - } - - @Nonnull - @Override - public ClassifyTableBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new ClassifyTableBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTableBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { - LOG.debug("Reading attributes for classify table: {}", id); - - final ClassifyTableKey key = id.firstKeyOf(ClassifyTable.class); - checkArgument(key != null, "could not find ClassifyTable key in {}", id); - final ClassifyTableInfo request = new ClassifyTableInfo(); - - final String tableName = key.getName(); - if (!classifyTableContext.containsTable(tableName, ctx.getMappingContext())) { - LOG.debug("Could not find classify table {} in the naming context", tableName); - return; - } - request.tableId = classifyTableContext.getTableIndex(tableName, ctx.getMappingContext()); - - - final ClassifyTableInfoReply reply = - getReplyForRead(getFutureJVpp().classifyTableInfo(request).toCompletableFuture(), id); - - // mandatory values: - builder.setName(tableName); - builder.setKey(key); - builder.setNbuckets(UnsignedInts.toLong(reply.nbuckets)); - builder.setSkipNVectors(UnsignedInts.toLong(reply.skipNVectors)); - - // optional value read from context - final Optional tableBaseNode = - classifyTableContext.getTableBaseNode(tableName, ctx.getMappingContext()); - if (tableBaseNode.isPresent()) { - builder.setClassifierNode(new VppNodeName(tableBaseNode.get())); - } - - builder.setMissNext( - readVppNode(reply.tableId, reply.missNextIndex, classifyTableContext, ctx.getMappingContext(), LOG) - .get()); - builder.setMask(new HexString(printHexBinary(reply.mask))); - builder.setActiveSessions(UnsignedInts.toLong(reply.activeSessions)); - - if (reply.nextTableIndex != ~0) { - // next table index is present: - builder.setNextTable(classifyTableContext.getTableName(reply.nextTableIndex, ctx.getMappingContext())); - } - - if (LOG.isTraceEnabled()) { - LOG.trace("Attributes for classify table {} successfully read: {}", id, builder.build()); - } - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext context) throws ReadFailedException { - LOG.debug("Reading list of keys for classify tables: {}", id); - - final ClassifyTableIdsReply classifyTableIdsReply = - getReplyForRead(getFutureJVpp().classifyTableIds(new ClassifyTableIds()).toCompletableFuture(), - id); - if (classifyTableIdsReply.ids != null) { - return Arrays.stream(classifyTableIdsReply.ids).mapToObj(i -> { - final String tableName = classifyTableContext.getTableName(i, context.getMappingContext()); - LOG.trace("Classify table with name: {} and index: {} found in VPP", tableName, i); - return new ClassifyTableKey(tableName); - }).collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, @Nonnull final ClassifyTable readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableBuilder(readValue) - .setName(readValue.getName()) - .build()); - } - - static InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InstanceIdentifier.create(VppClassifier.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey(id.firstKeyOf(ClassifyTable.class).getName())); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableWriter.java deleted file mode 100644 index 33dc64103..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableWriter.java +++ /dev/null @@ -1,149 +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.honeycomb.translate.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import javax.xml.bind.DatatypeConverter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer customizer responsible for classify table create/delete.
Sends {@code classify_add_del_table} message to - * VPP.
Equivalent to invoking {@code vppctl classify table} command. - */ -public class ClassifyTableWriter extends VppNodeWriter - implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableWriter.class); - private final VppClassifierContextManager classifyTableContext; - - public ClassifyTableWriter(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final VppClassifierContextManager classifyTableContext) { - super(futureJVppCore); - this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTable dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Creating classify table: iid={} dataAfter={}", id, dataAfter); - try { - final int newTableIndex = - classifyAddDelTable(true, id, dataAfter, ~0 /* value not present */, - writeContext.getMappingContext()); - - // Add classify table name <-> vpp index mapping to the naming context: - classifyTableContext.addTable(newTableIndex, dataAfter.getName(), dataAfter.getClassifierNode(), - writeContext.getMappingContext()); - LOG.debug("Successfully created classify table(id={]): iid={} dataAfter={}", newTableIndex, id, dataAfter); - } catch (VppBaseCallException e) { - throw new WriteFailedException.CreateFailedException(id, dataAfter, e); - } - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTable dataBefore, @Nonnull final ClassifyTable dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - throw new UnsupportedOperationException("Classify table update is not supported"); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTable dataBefore, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.debug("Removing classify table: iid={} dataBefore={}", id, dataBefore); - final String tableName = dataBefore.getName(); - checkState(classifyTableContext.containsTable(tableName, writeContext.getMappingContext()), - "Removing classify table {}, but index could not be found in the classify table context", tableName); - - final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); - try { - classifyAddDelTable(false, id, dataBefore, tableIndex, writeContext.getMappingContext()); - - // Remove deleted interface from interface context: - classifyTableContext.removeTable(dataBefore.getName(), writeContext.getMappingContext()); - LOG.debug("Successfully removed classify table(id={]): iid={} dataAfter={}", tableIndex, id, dataBefore); - } catch (VppBaseCallException e) { - throw new WriteFailedException.DeleteFailedException(id, e); - } - } - - private int classifyAddDelTable(final boolean isAdd, @Nonnull final InstanceIdentifier id, - @Nonnull final ClassifyTable table, final int tableId, final MappingContext ctx) - throws VppBaseCallException, WriteFailedException { - - final int missNextIndex = - getNodeIndex(table.getMissNext(), table, classifyTableContext, ctx, id); - - final CompletionStage createClassifyTableReplyCompletionStage = - getFutureJVpp() - .classifyAddDelTable(getClassifyAddDelTableRequest(isAdd, tableId, table, missNextIndex, ctx)); - - final ClassifyAddDelTableReply reply = - getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); - return reply.newTableIndex; - } - - private ClassifyAddDelTable getClassifyAddDelTableRequest(final boolean isAdd, final int tableIndex, - @Nonnull final ClassifyTable table, - final int missNextIndex, - @Nonnull final MappingContext ctx) { - final ClassifyAddDelTable request = new ClassifyAddDelTable(); - request.isAdd = booleanToByte(isAdd); - request.tableIndex = tableIndex; - - // mandatory, all u32 values are permitted: - request.nbuckets = table.getNbuckets().intValue(); - request.memorySize = table.getMemorySize().intValue(); - request.skipNVectors = table.getSkipNVectors().intValue(); - - // mandatory - request.missNextIndex = missNextIndex; - - final String nextTable = table.getNextTable(); - if (isAdd && nextTable != null) { - request.nextTableIndex = classifyTableContext.getTableIndex(nextTable, ctx); - } else { - request.nextTableIndex = ~0; // value not specified - } - request.mask = DatatypeConverter.parseHexBinary(table.getMask().getValue().replace(":", "")); - checkArgument(request.mask.length % 16 == 0, "Number of mask bytes must be multiple of 16."); - request.matchNVectors = request.mask.length / 16; - - return request; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManager.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManager.java deleted file mode 100644 index 69dfb644a..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManager.java +++ /dev/null @@ -1,106 +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.honeycomb.translate.v3po.vppclassifier; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; - -/** - * Manages metadata for vpp-classifier - */ -public interface VppClassifierContextManager { - - /** - * Creates metadata for classify table. - * - * @param id classify table index - * @param name classify table name - * @param classifierNode name of VPP node the table is defined for - * @param ctx mapping context providing context data for current transaction - */ - void addTable(final int id, @Nonnull final String name, @Nullable final VppNodeName classifierNode, - @Nonnull final MappingContext ctx); - - /** - * Check whether metadata for given classify table metadata is present. - * - * @param name classify table name - * @param ctx mapping context providing context data for current transaction - * @return true if present, false otherwise - */ - boolean containsTable(@Nonnull String name, @Nonnull final MappingContext ctx); - - /** - * Returns classify table index associated with the given name. - * - * @param name classify table name - * @param ctx mapping context providing context data for current transaction - * @return integer index value matching supplied classify table name - * @throws IllegalArgumentException if classify table was not found - */ - int getTableIndex(@Nonnull final String name, @Nonnull final MappingContext ctx); - - /** - * Retrieves classify table name for given id. If not present, artificial name will be generated. - * - * @param id classify table index - * @param ctx mapping context providing context data for current transaction - * @return classify table name matching supplied index - */ - String getTableName(final int id, @Nonnull final MappingContext ctx); - - /** - * Returns name of the base vpp node associated with the classify table. - * - * @param name classify table name - * @param ctx mapping context providing context data for current transaction - * @return name of VPP node the table is defined for - */ - Optional getTableBaseNode(final String name, @Nonnull final MappingContext ctx); - - /** - * Removes classify table metadata from current context. - * - * @param name classify table name - * @param ctx mapping context providing context data for current transaction - */ - void removeTable(@Nonnull final String name, @Nonnull final MappingContext ctx); - - /** - * Adds relative node index to node name mapping for given classify table. - * - * @param tableName classify table name - * @param nodeIndex index of a vpp node, relative to table's base node - * @param nodeName name of a vpp node - * @param ctx mapping context providing context data for current transaction - */ - void addNodeName(@Nonnull String tableName, final int nodeIndex, @Nonnull final String nodeName, - @Nonnull final MappingContext ctx); - - /** - * Retrieves node name associated with the given classify table and node index. - * - * @param tableIndex classify table index - * @param nodeIndex relative index of a vpp node - * @param ctx mapping context providing context data for current transaction - * @return name of vpp node - */ - Optional getNodeName(final int tableIndex, final int nodeIndex, @Nonnull final MappingContext ctx); -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManagerImpl.java deleted file mode 100644 index 13931ae47..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManagerImpl.java +++ /dev/null @@ -1,181 +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.honeycomb.translate.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.util.read.BindingBrokerReader; -import java.util.List; -import java.util.stream.Collector; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.inject.Named; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; - -/** - * Facade on top of {@link MappingContext} that manages {@link ClassifyTableContext}. - */ -public final class VppClassifierContextManagerImpl implements VppClassifierContextManager { - private static final Collector SINGLE_ITEM_COLLECTOR = - RWUtils.singleItemCollector(); - - @VisibleForTesting - static final InstanceIdentifier - VPP_CLASSIFIER_CONTEXT_IID = KeyedInstanceIdentifier.create(VppClassifierContext.class); - private final String artificialNamePrefix; - - /** - * Creates new VppClassifierContextManagerImpl. - * - * @param artificialNamePrefix artificial name to be used to generate names for classify tables without existing - * metadata - */ - public VppClassifierContextManagerImpl(@Nonnull final String artificialNamePrefix) { - this.artificialNamePrefix = - Preconditions.checkNotNull(artificialNamePrefix, "artificialNamePrefix should not be null"); - } - - private KeyedInstanceIdentifier getMappingIid(final String name) { - return VPP_CLASSIFIER_CONTEXT_IID.child(ClassifyTableContext.class, new ClassifyTableContextKey(name)); - } - - @Override - public void addTable(final int id, @Nonnull final String name, @Nullable final VppNodeName classifierNode, - @Nonnull final MappingContext ctx) { - final KeyedInstanceIdentifier mappingIid = getMappingIid(name); - final ClassifyTableContextBuilder tableCtx = new ClassifyTableContextBuilder().setIndex(id).setName(name); - if (classifierNode != null) { - tableCtx.setClassifierNodeName(classifierNode.getValue()); - } - ctx.put(mappingIid, tableCtx.build()); - } - - @Override - public boolean containsTable(@Nonnull final String name, @Nonnull final MappingContext ctx) { - final Optional read = ctx.read(getMappingIid(name)); - return read.isPresent(); - } - - @Override - public int getTableIndex(@Nonnull final String name, @Nonnull final MappingContext ctx) { - final Optional read = ctx.read(getMappingIid(name)); - checkArgument(read.isPresent(), "No mapping stored for name: %s", name); - return read.get().getIndex(); - } - - @Override - public String getTableName(final int id, @Nonnull final MappingContext ctx) { - if (!containsName(id, ctx)) { - final String artificialName = getArtificialName(id); - addTable(id, artificialName, null, ctx); - } - - final Optional read = ctx.read(VPP_CLASSIFIER_CONTEXT_IID); - checkState(read.isPresent(), "VppClassifierContext for index: %s is not present. But should be", id); - - return read.get().getClassifyTableContext().stream() - .filter(t -> t.getIndex().equals(id)) - .collect(SINGLE_ITEM_COLLECTOR).getName(); - } - - private boolean containsName(final int index, @Nonnull final MappingContext mappingContext) { - final Optional read = mappingContext.read(VPP_CLASSIFIER_CONTEXT_IID); - return read.isPresent() - ? read.get().getClassifyTableContext().stream().anyMatch(t -> t.getIndex().equals(index)) - : false; - } - - @Override - public Optional getTableBaseNode(@Nonnull final String name, @Nonnull final MappingContext ctx) { - final Optional read = ctx.read(getMappingIid(name)); - if (read.isPresent()) { - return Optional.fromNullable(read.get().getClassifierNodeName()); - } - return Optional.absent(); - } - - @Override - public void removeTable(@Nonnull final String name, @Nonnull final MappingContext ctx) { - ctx.delete(getMappingIid(name)); - } - - @Override - public void addNodeName(@Nonnull final String tableName, final int nodeIndex, - @Nonnull final String nodeName, - @Nonnull final MappingContext ctx) { - final KeyedInstanceIdentifier iid = - getMappingIid(tableName).child(NodeContext.class, new NodeContextKey(nodeName)); - ctx.put(iid, new NodeContextBuilder().setName(nodeName).setIndex(nodeIndex).build()); - } - - @Override - public Optional getNodeName(final int tableIndex, final int nodeIndex, @Nonnull final MappingContext ctx) { - if (!containsName(tableIndex, ctx)) { - return Optional.absent(); - } - final String tableName = getTableName(tableIndex, ctx); - final Optional tableCtx = ctx.read(getMappingIid(tableName)); - final List nodeContext = tableCtx.get().getNodeContext(); - if (nodeContext == null) { - return Optional.absent(); - } - return Optional.fromNullable(nodeContext.stream() - .filter(n -> n.getIndex().equals(nodeIndex)) - .findFirst() - .map(nodes -> nodes.getName()) - .orElse(null)); - } - - private String getArtificialName(final int index) { - return artificialNamePrefix + index; - } - - public static final class ContextsReaderFactory implements ReaderFactory { - - @Inject - @Named("honeycomb-context") - private DataBroker contextBindingBrokerDependency; - - @Override - public void init(final ModifiableReaderRegistryBuilder registry) { - registry.add(new BindingBrokerReader<>(VPP_CLASSIFIER_CONTEXT_IID, - contextBindingBrokerDependency, - LogicalDatastoreType.OPERATIONAL, VppClassifierContextBuilder.class)); - } - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppNodeReader.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppNodeReader.java deleted file mode 100644 index 23ce094c1..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppNodeReader.java +++ /dev/null @@ -1,45 +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.honeycomb.translate.v3po.vppclassifier; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.slf4j.Logger; - -interface VppNodeReader { - - /** - * Converts vpp node index to YANG representation of vpp node. - * - * @param nodeIndex index of vpp node treated as signed integer. - * @return vpp node representation - */ - default Optional readVppNode(final int tableIndex, final int nodeIndex, - @Nonnull final VppClassifierContextManager vppClassifierContextManager, - @Nonnull final MappingContext ctx, @Nonnull final Logger log) { - final PacketHandlingAction action = PacketHandlingAction.forValue(nodeIndex); - if (action == null) { - return vppClassifierContextManager.getNodeName(tableIndex, nodeIndex, ctx) - .transform(nodeName -> new VppNode(new VppNodeName(nodeName))); - } - return Optional.of(new VppNode(action)); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppNodeWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppNodeWriter.java deleted file mode 100644 index 308c2496e..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppNodeWriter.java +++ /dev/null @@ -1,79 +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.honeycomb.translate.v3po.vppclassifier; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.GetNextIndex; -import io.fd.vpp.jvpp.core.dto.GetNextIndexReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -abstract class VppNodeWriter extends FutureJVppCustomizer implements JvppReplyConsumer { - - protected VppNodeWriter(@Nonnull final FutureJVppCore futureJvpp) { - super(futureJvpp); - } - - protected int getNodeIndex(@Nonnull final VppNode node, @Nonnull final ClassifyTable classifyTable, - @Nonnull final VppClassifierContextManager vppClassifierContextManager, - @Nonnull final MappingContext ctx, @Nonnull final InstanceIdentifier id) - throws VppBaseCallException, WriteFailedException { - if (node.getPacketHandlingAction() != null) { - return node.getPacketHandlingAction().getIntValue(); - } else { - return nodeNameToIndex(classifyTable, node.getVppNodeName().getValue(), vppClassifierContextManager, ctx, - id); - } - } - - private int nodeNameToIndex(@Nonnull final ClassifyTable classifyTable, @Nonnull final String nextNodeName, - @Nonnull final VppClassifierContextManager vppClassifierContextManager, - @Nonnull final MappingContext ctx, @Nonnull final InstanceIdentifier id) - throws WriteFailedException { - checkArgument(classifyTable != null && classifyTable.getClassifierNode() != null, - "to use relative node names, table classifier node needs to be provided"); - final GetNextIndex request = new GetNextIndex(); - request.nodeName = classifyTable.getClassifierNode().getValue().getBytes(); - request.nextName = nextNodeName.getBytes(); - final CompletionStage getNextIndexCompletionStage = - getFutureJVpp().getNextIndex(request); - - final GetNextIndexReply reply; - try { - reply = getReplyForRead(getNextIndexCompletionStage.toCompletableFuture(), id); - - // vpp does not provide relative node index to node name conversion (https://jira.fd.io/browse/VPP-219) - // as a workaround we need to add mapping to vpp-classfier-context - vppClassifierContextManager.addNodeName(classifyTable.getName(), reply.nextIndex, nextNodeName, ctx); - } catch (ReadFailedException e) { - throw new WriteFailedException(id, String.format("Failed to get node index for %s relative to %s", - nextNodeName, classifyTable.getClassifierNode()), e); - } - return reply.nextIndex; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/BridgeDomainCustomizer.java deleted file mode 100644 index 9f122d1a5..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/BridgeDomainCustomizer.java +++ /dev/null @@ -1,181 +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.honeycomb.translate.v3po.vppstate; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Iterables; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Vpp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; -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 BridgeDomainCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, ByteDataTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); - private final NamingContext bdContext; - - public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext bdContext) { - super(futureJVppCore); - this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomainBuilder builder, @Nonnull final ReadContext context) - throws ReadFailedException { - LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: id={}, builderbuilder={}, context={}", - id, builder, context); - - final BridgeDomainKey key = id.firstKeyOf(id.getTargetType()); - LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: key={}", key); - - final int bdId = bdContext.getIndex(key.getName(), context.getMappingContext()); - LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: bdId={}", bdId); - - BridgeDomainDetailsReplyDump reply; - BridgeDomainDetails bridgeDomainDetails; - final BridgeDomainDump request = new BridgeDomainDump(); - request.bdId = bdContext.getIndex(key.getName(), context.getMappingContext()); - try { - reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get(); - bridgeDomainDetails = Iterables.getOnlyElement(reply.bridgeDomainDetails); - } catch (Exception e) { - LOG.debug("Unable to read bridge domain: {}", key.getName(), e); - return; - } - - logBridgeDomainDetails(bridgeDomainDetails); - - builder.setName(key.getName()); - builder.setArpTermination(byteToBoolean(bridgeDomainDetails.arpTerm)); - builder.setFlood(byteToBoolean(bridgeDomainDetails.flood)); - builder.setForward(byteToBoolean(bridgeDomainDetails.forward)); - builder.setLearn(byteToBoolean(bridgeDomainDetails.learn)); - builder.setUnknownUnicastFlood(byteToBoolean(bridgeDomainDetails.uuFlood)); - } - - private void logBridgeDomainDetails(final BridgeDomainDetails bridgeDomainDetails) { - LOG.debug("bridgeDomainDetails={}", bridgeDomainDetails); - if (bridgeDomainDetails != null) { - LOG.debug("bridgeDomainDetails.arpTerm={}", bridgeDomainDetails.arpTerm); - LOG.debug("bridgeDomainDetails.bdId={}", bridgeDomainDetails.bdId); - LOG.debug("bridgeDomainDetails.bviSwIfIndex={}", bridgeDomainDetails.bviSwIfIndex); - LOG.debug("bridgeDomainDetails.flood={}", bridgeDomainDetails.flood); - LOG.debug("bridgeDomainDetails.forward={}", bridgeDomainDetails.forward); - LOG.debug("bridgeDomainDetails.learn={}", bridgeDomainDetails.learn); - LOG.debug("bridgeDomainDetails.nSwIfs={}", bridgeDomainDetails.nSwIfs); - LOG.debug("bridgeDomainDetails.uuFlood={}", bridgeDomainDetails.uuFlood); - } - } - - @Nonnull - @Override - public BridgeDomainBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new BridgeDomainBuilder(); - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext context) throws ReadFailedException { - final BridgeDomainDump request = new BridgeDomainDump(); - request.bdId = -1; // dump call - - BridgeDomainDetailsReplyDump reply; - try { - reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get(); - } catch (Exception e) { - throw new ReadFailedException(id, e); - } - - if (reply == null || reply.bridgeDomainDetails == null) { - return Collections.emptyList(); - } - - final int bIdsLength = reply.bridgeDomainDetails.size(); - LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bIds.length={}", bIdsLength); - if (bIdsLength == 0) { - // No bridge domains - return Collections.emptyList(); - } - - final List allIds = new ArrayList<>(bIdsLength); - for (BridgeDomainDetails detail : reply.bridgeDomainDetails) { - logBridgeDomainDetails(detail); - - final String bName = bdContext.getName(detail.bdId, context.getMappingContext()); - LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bName={}", bName); - allIds.add(new BridgeDomainKey(bName)); - } - - return allIds; - } - - @Override - public void merge(@Nonnull final Builder builder, - @Nonnull final List readData) { - ((BridgeDomainsBuilder) builder).setBridgeDomain(readData); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainBuilder() - .setName(readValue.getName()) - .setLearn(readValue.isLearn()) - .setUnknownUnicastFlood(readValue.isUnknownUnicastFlood()) - .setArpTermination(readValue.isArpTermination()) - .setFlood(readValue.isFlood()) - .setForward(readValue.isForward()) - .build()); - } - - static InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InstanceIdentifier.create(Vpp.class).child(BridgeDomains.class).child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey( - id.firstKeyOf(BridgeDomain.class).getName())); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/L2FibEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/L2FibEntryCustomizer.java deleted file mode 100644 index a9326d97f..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/L2FibEntryCustomizer.java +++ /dev/null @@ -1,165 +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.honeycomb.translate.v3po.vppstate; - -import com.google.common.base.Preconditions; -import com.google.common.primitives.Longs; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceDataTranslator; -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.L2FibTableDump; -import io.fd.vpp.jvpp.core.dto.L2FibTableEntry; -import io.fd.vpp.jvpp.core.dto.L2FibTableEntryReplyDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibForward; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; -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 L2FibEntryCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, ByteDataTranslator, - InterfaceDataTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); - - private static final Collector SINGLE_ITEM_COLLECTOR = - RWUtils.singleItemCollector(); - - private final NamingContext bdContext; - private final NamingContext interfaceContext; - - public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntryBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { - - final L2FibEntryKey key = id.firstKeyOf(id.getTargetType()); - final BridgeDomainKey bridgeDomainKey = id.firstKeyOf(BridgeDomain.class); - final int bdId = bdContext.getIndex(bridgeDomainKey.getName(), ctx.getMappingContext()); - LOG.debug("Reading L2 FIB entry: key={}. bridgeDomainKey={}, bdId={}", key, bridgeDomainKey, bdId); - - try { - // TODO HONEYCOMB-186 use cached l2FibTable - final L2FibTableEntry entry = dumpL2Fibs(id, bdId).stream().filter(e -> key.getPhysAddress() - .equals(new PhysAddress(vppPhysAddrToYang(Longs.toByteArray(e.mac), 2)))) - .collect(SINGLE_ITEM_COLLECTOR); - - builder.setAction(byteToBoolean(entry.filterMac) - ? L2FibFilter.class - : L2FibForward.class); - builder.setBridgedVirtualInterface(byteToBoolean(entry.bviMac)); - - if (entry.swIfIndex != -1) { - builder.setOutgoingInterface(interfaceContext.getName(entry.swIfIndex, ctx.getMappingContext())); - } - builder.setStaticConfig(byteToBoolean(entry.staticMac)); - builder.setPhysAddress(key.getPhysAddress()); - builder.setKey(key); - } catch (Exception e) { - throw new ReadFailedException(id, e); - } - } - - @Nonnull - private List dumpL2Fibs(final InstanceIdentifier id, final int bdId) - throws ReadFailedException { - final L2FibTableDump l2FibRequest = new L2FibTableDump(); - l2FibRequest.bdId = bdId; - - final CompletableFuture l2FibTableDumpCompletableFuture = - getFutureJVpp().l2FibTableDump(l2FibRequest).toCompletableFuture(); - - final L2FibTableEntryReplyDump dump = getReplyForRead(l2FibTableDumpCompletableFuture, id); - - if (null == dump || null == dump.l2FibTableEntry) { - return Collections.emptyList(); - } else { - return dump.l2FibTableEntry; - } - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext ctx) throws ReadFailedException { - final BridgeDomainKey bridgeDomainKey = id.firstKeyOf(BridgeDomain.class); - final int bdId = bdContext.getIndex(bridgeDomainKey.getName(), ctx.getMappingContext()); - - LOG.debug("Reading L2 FIB for bridge domain {} (bdId={})", bridgeDomainKey, bdId); - return dumpL2Fibs(id, bdId).stream() - .map(entry -> new L2FibEntryKey( - new PhysAddress(vppPhysAddrToYang(Longs.toByteArray(entry.mac), 2)))) - .collect(Collectors.toList()); - } - - @Override - public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { - ((L2FibTableBuilder) builder).setL2FibEntry(readData); - } - - @Nonnull - @Override - public L2FibEntryBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new L2FibEntryBuilder(); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntry readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - // Convert operational object to config. VPP does not support setting BVI (see v3po.yang) - new L2FibEntryBuilder(readValue).setBridgedVirtualInterface(null).build()); - } - - static InstanceIdentifier getCfgId( - final @Nonnull InstanceIdentifier id) { - return BridgeDomainCustomizer.getCfgId(RWUtils.cutId(id, BridgeDomain.class)).child( - L2FibTable.class).child(L2FibEntry.class, new L2FibEntryKey(id.firstKeyOf(L2FibEntry.class))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/VersionCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/VersionCustomizer.java deleted file mode 100644 index dfa0f9632..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/vppstate/VersionCustomizer.java +++ /dev/null @@ -1,82 +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.honeycomb.translate.v3po.vppstate; - -import com.google.common.primitives.UnsignedInts; -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.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; -import io.fd.vpp.jvpp.core.dto.ShowVersion; -import io.fd.vpp.jvpp.core.dto.ShowVersionReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import io.fd.vpp.jvpp.dto.ControlPing; -import io.fd.vpp.jvpp.dto.ControlPingReply; -import io.fd.vpp.jvpp.dto.JVppReply; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.VersionBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class VersionCustomizer - extends FutureJVppCustomizer - implements ReaderCustomizer, ByteDataTranslator, JvppReplyConsumer { - - public VersionCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { - super(futureJVppCore); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Version readValue) { - ((VppStateBuilder) parentBuilder).setVersion(readValue); - } - - @Nonnull - @Override - public VersionBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new VersionBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final VersionBuilder builder, - @Nonnull final ReadContext context) throws ReadFailedException { - - // Execute with timeout - final CompletionStage showVersionFuture = getFutureJVpp().showVersion(new ShowVersion()); - final ShowVersionReply reply = getReplyForRead(showVersionFuture.toCompletableFuture(), id); - - builder.setBranch(toString(reply.version)); - builder.setName(toString(reply.program)); - builder.setBuildDate(toString(reply.buildDate)); - builder.setBuildDirectory(toString(reply.buildDirectory)); - builder.setPid(getPid(id)); - } - - private Long getPid(@Nonnull final InstanceIdentifier id) throws ReadFailedException { - final CompletionStage> request = getFutureJVpp().send(new ControlPing()); - final ControlPingReply reply = (ControlPingReply)getReplyForRead(request.toCompletableFuture(), id); - return UnsignedInts.toLong(reply.vpePid); - } - - -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/vpp/util/SubInterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/vpp/util/SubInterfaceUtils.java deleted file mode 100644 index d27dd1e3e..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/vpp/util/SubInterfaceUtils.java +++ /dev/null @@ -1,52 +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.honeycomb.translate.vpp.util; - -import java.util.List; -import javax.annotation.Nonnegative; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; - -public final class SubInterfaceUtils { - - private SubInterfaceUtils() { - throw new UnsupportedOperationException("Utility class cannot be instantiated."); - } - - public static String getSubInterfaceName(final String superIfName, final int subIfaceId) { - return String.format("%s.%d", superIfName, subIfaceId); - } - - /** - * Returns number of sub-interface tags. - * - * @param tags data object that represents sub-interface tags - * @return number of sub interface tags - */ - @Nonnegative - public static int getNumberOfTags(@Nullable final Tags tags) { - if (tags == null) { - return 0; - } - final List tagList = tags.getTag(); - if (tagList == null) { - return 0; - } - return tagList.size(); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/DisabledInterfacesManagerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/DisabledInterfacesManagerTest.java new file mode 100644 index 000000000..94c95bcf6 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/DisabledInterfacesManagerTest.java @@ -0,0 +1,109 @@ +/* + * 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; + + + + +import static org.hamcrest.CoreMatchers.hasItems; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.DisabledInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.DisabledInterfacesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndex; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndexBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndexKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +public class DisabledInterfacesManagerTest { + + private static final InstanceIdentifier + ROOT_ID = InstanceIdentifier.create(DisabledInterfaces.class); + private static final KeyedInstanceIdentifier SPECIFIC_ID_1 = + ROOT_ID.child(DisabledInterfaceIndex.class, new DisabledInterfaceIndexKey(1)); + private static final KeyedInstanceIdentifier SPECIFIC_ID_4 = + ROOT_ID.child(DisabledInterfaceIndex.class, new DisabledInterfaceIndexKey(4)); + + @Mock + private MappingContext mappingContext; + private DisabledInterfacesManager manager; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + manager = new DisabledInterfacesManager(); + doReturn(Optional.of(new DisabledInterfacesBuilder().setDisabledInterfaceIndex(toIndices(1, 2, 3)).build())) + .when(mappingContext) + .read(ROOT_ID); + doReturn(Optional.of(toIndex(1))) + .when(mappingContext) + .read(SPECIFIC_ID_1); + doReturn(Optional.absent()) + .when(mappingContext) + .read(SPECIFIC_ID_4); + } + + @Test + public void testGetAll() throws Exception { + final List disabledInterfaces = manager.getDisabledInterfaces(mappingContext); + assertThat(disabledInterfaces, hasItems(1, 2, 3)); + } + + @Test + public void testCheckOne() throws Exception { + assertTrue(manager.isInterfaceDisabled(1, mappingContext)); + assertFalse(manager.isInterfaceDisabled(4, mappingContext)); + } + + @Test + public void testDisable() throws Exception { + manager.disableInterface(1, mappingContext); + verify(mappingContext).put(SPECIFIC_ID_1, toIndex(1)); + } + + @Test + public void testRemoveDisability() throws Exception { + manager.removeDisabledInterface(1, mappingContext); + verify(mappingContext).delete(SPECIFIC_ID_1); + } + + private List toIndices(final int... indices) { + return Arrays.stream(indices) + .mapToObj(this::toIndex) + .collect(Collectors.toList()); + } + + private DisabledInterfaceIndex toIndex(final int idx) { + return new DisabledInterfaceIndexBuilder() + .setIndex(idx) + .build(); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/V3poModuleTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/V3poModuleTest.java new file mode 100644 index 000000000..3366af64f --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/V3poModuleTest.java @@ -0,0 +1,96 @@ +/* + * 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; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.Matchers.empty; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; +import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; +import io.fd.honeycomb.translate.write.WriterFactory; +import java.util.HashSet; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +public class V3poModuleTest { + + @Named("honeycomb-context") + @Bind + @Mock + private MappingContext mappingContext; + + @Named("honeycomb-initializer") + @Bind + @Mock + private DataBroker honeycombInitializer; + + @Named("honeycomb-context") + @Bind + @Mock + private DataBroker honeycombContext; + + @Bind + @Mock + private FutureJVppCore futureJVppCore; + + @Inject + private Set readerFactories = new HashSet<>(); + + @Inject + private Set writerFactories = new HashSet<>(); + + @Before + public void setUp() { + initMocks(this); + Guice.createInjector(new V3poModule(), BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testReaderFactories() throws Exception { + assertThat(readerFactories, is(not(empty()))); + + // Test registration process (all dependencies present, topological order of readers does exist, etc.) + final CompositeReaderRegistryBuilder registryBuilder = new CompositeReaderRegistryBuilder(); + readerFactories.stream().forEach(factory -> factory.init(registryBuilder)); + assertNotNull(registryBuilder.build()); + } + + @Test + public void testWriterFactories() throws Exception { + assertThat(writerFactories, is(not(empty()))); + + // Test registration process (all dependencies present, topological order of writers does exist, etc.) + final FlatWriterRegistryBuilder registryBuilder = new FlatWriterRegistryBuilder(); + writerFactories.stream().forEach(factory -> factory.init(registryBuilder)); + assertNotNull(registryBuilder.build()); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AclCustomizerTest.java new file mode 100644 index 000000000..7f55ae60a --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AclCustomizerTest.java @@ -0,0 +1,156 @@ +/* + * 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; + +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import io.fd.hc2vpp.v3po.interfaces.acl.ingress.AclCustomizer; +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import org.junit.Test; +import org.mockito.Mock; +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.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AclCustomizerTest extends WriterCustomizerTest { + + @Mock + private VppClassifierContextManager classifyTableContext; + + private AclCustomizer customizer; + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + + private static final int ACL_TABLE_INDEX = 0; + private static final String ACL_TABLE_NAME = "table0"; + + @Override + public void setUp() { + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + customizer = new AclCustomizer(api, new NamingContext("generatedInterfaceName", IFC_TEST_INSTANCE), + classifyTableContext); + } + + private InstanceIdentifier getAclId(final String name) { + return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation( + VppInterfaceAugmentation.class).child(Acl.class).child(Ingress.class); + } + + private Ingress generateAcl(final String tableName) { + final IngressBuilder builder = new IngressBuilder(); + final L2Acl l2Acl = new L2AclBuilder().setClassifyTable(tableName).build(); + builder.setL2Acl(l2Acl); + return builder.build(); + } + + private void whenInputAclSetInterfaceThenSuccess() { + doReturn(future(new InputAclSetInterfaceReply())).when(api) + .inputAclSetInterface(any(InputAclSetInterface.class)); + } + + private void whenInputAclSetInterfaceThenFailure() { + doReturn(failedFuture()).when(api).inputAclSetInterface(any(InputAclSetInterface.class)); + } + + private static InputAclSetInterface generateInputAclSetInterface(final byte isAdd, final int ifIndex, + final int l2TableIndex) { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = isAdd; + request.l2TableIndex = l2TableIndex; + request.ip4TableIndex = ~0; + request.ip6TableIndex = ~0; + request.swIfIndex = ifIndex; + return request; + } + + @Test + public void testCreate() throws Exception { + final Ingress acl = generateAcl(ACL_TABLE_NAME); + final InstanceIdentifier id = getAclId(IF_NAME); + + whenInputAclSetInterfaceThenSuccess(); + + customizer.writeCurrentAttributes(id, acl, writeContext); + + verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 1, IF_INDEX, ACL_TABLE_INDEX)); + } + + @Test + public void testCreateFailed() throws Exception { + final Ingress acl = generateAcl(ACL_TABLE_NAME); + final InstanceIdentifier id = getAclId(IF_NAME); + + whenInputAclSetInterfaceThenFailure(); + + try { + customizer.writeCurrentAttributes(id, acl, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 1, IF_INDEX, ACL_TABLE_INDEX)); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testDelete() throws Exception { + final Ingress acl = generateAcl(ACL_TABLE_NAME); + final InstanceIdentifier id = getAclId(IF_NAME); + + whenInputAclSetInterfaceThenSuccess(); + + customizer.deleteCurrentAttributes(id, acl, writeContext); + + verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 0, IF_INDEX, ACL_TABLE_INDEX)); + } + + @Test + public void testDeleteFailed() throws Exception { + final Ingress acl = generateAcl(ACL_TABLE_NAME); + final InstanceIdentifier id = getAclId(IF_NAME); + + whenInputAclSetInterfaceThenFailure(); + + try { + customizer.deleteCurrentAttributes(id, acl, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 0, IF_INDEX, ACL_TABLE_INDEX)); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizerTest.java new file mode 100644 index 000000000..da75fa92d --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizerTest.java @@ -0,0 +1,197 @@ +/* + * 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; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import com.google.common.net.InetAddresses; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.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.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.GreBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.GreAddDelTunnel; +import io.fd.vpp.jvpp.core.dto.GreAddDelTunnelReply; + +public class GreCustomizerTest extends WriterCustomizerTest { + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private final String IFACE_NAME = "eth0"; + private final int IFACE_ID = 1; + private InstanceIdentifier id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(Gre.class); + private static final byte ADD_GRE = 1; + private static final byte DEL_GRE = 0; + + private GreCustomizer customizer; + + @Override + public void setUp() throws Exception { + InterfaceTypeTestUtils.setupWriteContext(writeContext, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.GreTunnel.class); + customizer = new GreCustomizer(api, new NamingContext("generateInterfaceNAme", IFC_TEST_INSTANCE)); + } + + private void whenGreAddDelTunnelThenSuccess() { + final GreAddDelTunnelReply reply = new GreAddDelTunnelReply(); + reply.swIfIndex = IFACE_ID; + doReturn(future(reply)).when(api).greAddDelTunnel(any(GreAddDelTunnel.class)); + } + + private void whenGreAddDelTunnelThenFailure() { + doReturn(failedFuture()).when(api).greAddDelTunnel(any(GreAddDelTunnel.class)); + } + + private GreAddDelTunnel verifyGreAddDelTunnelWasInvoked(final Gre gre) throws VppInvocationException { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(GreAddDelTunnel.class); + verify(api).greAddDelTunnel(argumentCaptor.capture()); + final GreAddDelTunnel actual = argumentCaptor.getValue(); + assertEquals(0, actual.isIpv6); + assertArrayEquals(InetAddresses.forString(gre.getSrc().getIpv4Address().getValue()).getAddress(), + actual.srcAddress); + assertArrayEquals(InetAddresses.forString(gre.getDst().getIpv4Address().getValue()).getAddress(), + actual.dstAddress); + assertEquals(gre.getOuterFibId().intValue(), actual.outerFibId); + return actual; + } + + private void verifyGreAddWasInvoked(final Gre gre) throws VppInvocationException { + final GreAddDelTunnel actual = verifyGreAddDelTunnelWasInvoked(gre); + assertEquals(ADD_GRE, actual.isAdd); + } + + private void verifyGreDeleteWasInvoked(final Gre gre) throws VppInvocationException { + final GreAddDelTunnel actual = verifyGreAddDelTunnelWasInvoked(gre); + assertEquals(DEL_GRE, actual.isAdd); + } + + private static Gre generateGre() { + final GreBuilder builder = new GreBuilder(); + builder.setSrc(new IpAddress(new Ipv4Address("192.168.20.10"))); + builder.setDst(new IpAddress(new Ipv4Address("192.168.20.11"))); + builder.setOuterFibId(Long.valueOf(123)); + return builder.build(); + } + + @Test + public void testWriteCurrentAttributes() throws Exception { + final Gre gre = generateGre(); + + whenGreAddDelTunnelThenSuccess(); + + noMappingDefined(mappingContext, IFACE_NAME, IFC_TEST_INSTANCE); + + customizer.writeCurrentAttributes(id, gre, writeContext); + verifyGreAddWasInvoked(gre); + verify(mappingContext).put(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE)), + eq(mapping(IFACE_NAME, IFACE_ID).get())); + } + + @Test + public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception { + final Gre gre = generateGre(); + + whenGreAddDelTunnelThenSuccess(); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_TEST_INSTANCE); + + customizer.writeCurrentAttributes(id, gre, writeContext); + verifyGreAddWasInvoked(gre); + + // Remove the first mapping before putting in the new one + verify(mappingContext).delete(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE))); + verify(mappingContext).put(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE)), eq(mapping(IFACE_NAME, IFACE_ID).get())); + } + + @Test + public void testWriteCurrentAttributesFailed() throws Exception { + final Gre gre = generateGre(); + + whenGreAddDelTunnelThenFailure(); + + try { + customizer.writeCurrentAttributes(id, gre, writeContext); + } catch (WriteFailedException.CreateFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyGreAddWasInvoked(gre); + // Mapping not stored due to failure + verify(mappingContext, times(0)).put(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE)), eq(mapping( + IFACE_NAME, 0).get())); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testUpdateCurrentAttributes() throws Exception { + try { + customizer.updateCurrentAttributes(id, generateGre(), generateGre(), writeContext); + } catch (WriteFailedException.UpdateFailedException e) { + assertEquals(UnsupportedOperationException.class, e.getCause().getClass()); + return; + } + fail("WriteFailedException.UpdateFailedException was expected"); + } + + @Test + public void testDeleteCurrentAttributes() throws Exception { + final Gre gre = generateGre(); + + whenGreAddDelTunnelThenSuccess(); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_TEST_INSTANCE); + + customizer.deleteCurrentAttributes(id, gre, writeContext); + verifyGreDeleteWasInvoked(gre); + verify(mappingContext).delete(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE))); + } + + @Test + public void testDeleteCurrentAttributesaFailed() throws Exception { + final Gre gre = generateGre(); + + whenGreAddDelTunnelThenFailure(); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_TEST_INSTANCE); + + try { + customizer.deleteCurrentAttributes(id, gre, writeContext); + } catch (WriteFailedException.DeleteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyGreDeleteWasInvoked(gre); + verify(mappingContext, times(0)).delete(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE))); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceCustomizerTest.java new file mode 100644 index 000000000..c72d43a02 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceCustomizerTest.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; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +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.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlags; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsReply; + +public class InterfaceCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { + private static final String IFACE_CTX_NAME = "interface-ctx"; + private static final String IF_NAME = "eth1"; + private static final int IF_INDEX = 1; + + private InterfaceCustomizer customizer; + private InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)); + + @Override + protected void setUp() throws Exception { + customizer = new InterfaceCustomizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME); + } + + @Test + public void testWrite() throws WriteFailedException { + final boolean enabled = true; + when(api.swInterfaceSetFlags(any())).thenReturn(future(new SwInterfaceSetFlagsReply())); + customizer.writeCurrentAttributes(IID, iface(enabled), writeContext); + verify(api).swInterfaceSetFlags(expectedRequest(enabled)); + } + + @Test + public void testWriteFailed() { + final boolean enabled = false; + when(api.swInterfaceSetFlags(any())).thenReturn(failedFuture()); + try { + customizer.writeCurrentAttributes(IID, iface(enabled), writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).swInterfaceSetFlags(expectedRequest(enabled)); + return; + } + fail("WriteFailedException expected"); + } + + @Test + public void testUpdate() throws WriteFailedException { + when(api.swInterfaceSetFlags(any())).thenReturn(future(new SwInterfaceSetFlagsReply())); + customizer.updateCurrentAttributes(IID, iface(false), iface(true), writeContext); + verify(api).swInterfaceSetFlags(expectedRequest(true)); + } + + @Test + public void testUpdateFailed() { + when(api.swInterfaceSetFlags(any())).thenReturn(failedFuture()); + try { + customizer.updateCurrentAttributes(IID, iface(false), iface(true), writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).swInterfaceSetFlags(expectedRequest(true)); + return; + } + fail("WriteFailedException expected"); + } + + @Test + public void testDelete() throws WriteFailedException { + customizer.deleteCurrentAttributes(IID, mock(Interface.class), writeContext); + verifyZeroInteractions(api); + } + + private Interface iface(final boolean enabled) { + return new InterfaceBuilder().setName(IF_NAME).setEnabled(enabled).build(); + } + + private SwInterfaceSetFlags expectedRequest(final boolean enabled) { + final SwInterfaceSetFlags request = new SwInterfaceSetFlags(); + request.deleted = 0; + request.adminUpDown = booleanToByte(enabled); + request.linkUpDown = booleanToByte(enabled); + request.swIfIndex = IF_INDEX; + return request; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceTypeTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceTypeTestUtils.java new file mode 100644 index 000000000..5bce6aea1 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceTypeTestUtils.java @@ -0,0 +1,40 @@ +/* + * 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; + +import static org.mockito.Mockito.doReturn; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.write.WriteContext; +import org.mockito.Matchers; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +final class InterfaceTypeTestUtils { + + private InterfaceTypeTestUtils() {} + + static void setupWriteContext(final WriteContext writeContext, final Class ifcType) { + doReturn(new ModificationCache()).when(writeContext).getModificationCache(); + doReturn(Optional.of(new InterfaceBuilder() + .setType(ifcType) + .build())).when(writeContext).readAfter(Matchers.any(InstanceIdentifier.class)); + } + +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/L2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/L2CustomizerTest.java new file mode 100644 index 000000000..d54bd3392 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/L2CustomizerTest.java @@ -0,0 +1,150 @@ +/* + * 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; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +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.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBased; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBased; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBasedBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Bridge; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2BridgeReply; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Xconnect; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2XconnectReply; + +public class L2CustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { + private static final String IFACE_CTX_NAME = "interface-ctx"; + private static final String BD_CTX_NAME = "bd-ctx"; + private static final String IF1_NAME = "eth1"; + private static final int IF1_INDEX = 1; + private static final String IF2_NAME = "eth2"; + private static final int IF2_INDEX = 2; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF1_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(L2.class); + private static final String BD_NAME = "test_bd"; + private static final int BD_INDEX = 13; + + private L2Customizer customizer; + + @Override + protected void setUp() throws Exception { + customizer = new L2Customizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME), + new NamingContext("bdPrefix", BD_CTX_NAME)); + defineMapping(mappingContext, IF1_NAME, IF1_INDEX, IFACE_CTX_NAME); + defineMapping(mappingContext, IF2_NAME, IF2_INDEX, IFACE_CTX_NAME); + defineMapping(mappingContext, BD_NAME, BD_INDEX, BD_CTX_NAME); + } + + @Test + public void testWrite() throws WriteFailedException { + when(api.swInterfaceSetL2Xconnect(any())).thenReturn(future(new SwInterfaceSetL2XconnectReply())); + customizer.writeCurrentAttributes(IID, l2(xconnectBased()), writeContext); + verify(api).swInterfaceSetL2Xconnect(xconnectRequest(true)); + } + + @Test + public void testWriteFailed() { + when(api.swInterfaceSetL2Bridge(any())).thenReturn(failedFuture()); + try { + customizer.writeCurrentAttributes(IID, l2(bridgeBased(false)), writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).swInterfaceSetL2Bridge(bridgeRequest(false, true)); + return; + } + fail("WriteFailedException expected"); + } + + @Test + public void testUpdate() throws WriteFailedException { + when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply())); + customizer.updateCurrentAttributes(IID, l2(bridgeBased(false)), l2(bridgeBased(true)), writeContext); + verify(api).swInterfaceSetL2Bridge(bridgeRequest(true, true)); + } + + @Test + public void testDelete() throws WriteFailedException { + when(api.swInterfaceSetL2Xconnect(any())).thenReturn(future(new SwInterfaceSetL2XconnectReply())); + customizer.deleteCurrentAttributes(IID, l2(xconnectBased()), writeContext); + verify(api).swInterfaceSetL2Xconnect(xconnectRequest(false)); + } + + @Test + public void testDeleteFailed() { + when(api.swInterfaceSetL2Bridge(any())).thenReturn(failedFuture()); + try { + customizer.deleteCurrentAttributes(IID, l2(bridgeBased(true)), writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).swInterfaceSetL2Bridge(bridgeRequest(true, false)); + return; + } + fail("WriteFailedException expected"); + } + + private XconnectBased xconnectBased() { + return new XconnectBasedBuilder().setXconnectOutgoingInterface(IF2_NAME).build(); + } + + private SwInterfaceSetL2Xconnect xconnectRequest(final boolean enable) { + final SwInterfaceSetL2Xconnect request = new SwInterfaceSetL2Xconnect(); + request.rxSwIfIndex = IF1_INDEX; + request.txSwIfIndex = IF2_INDEX; + request.enable = booleanToByte(enable); + return request; + } + + private BridgeBased bridgeBased(final boolean bvi) { + return new BridgeBasedBuilder().setBridgedVirtualInterface(bvi) + .setBridgeDomain(BD_NAME).setSplitHorizonGroup((short) 123).build(); + } + + private SwInterfaceSetL2Bridge bridgeRequest(final boolean bvi, final boolean enable) { + final SwInterfaceSetL2Bridge request = new SwInterfaceSetL2Bridge(); + request.bdId = BD_INDEX; + request.rxSwIfIndex = IF1_INDEX; + request.bvi = booleanToByte(bvi); + request.enable = booleanToByte(enable); + request.shg = 123; + return request; + } + + + private L2 l2(final Interconnection interconnection) { + return new L2Builder().setInterconnection(interconnection).build(); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/LoopbackCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/LoopbackCustomizerTest.java new file mode 100644 index 000000000..67c90343e --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/LoopbackCustomizerTest.java @@ -0,0 +1,105 @@ +/* + * 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; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.core.dto.CreateLoopback; +import io.fd.vpp.jvpp.core.dto.CreateLoopbackReply; +import io.fd.vpp.jvpp.core.dto.DeleteLoopback; +import io.fd.vpp.jvpp.core.dto.DeleteLoopbackReply; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +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.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Loopback; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.LoopbackBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class LoopbackCustomizerTest extends WriterCustomizerTest { + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private LoopbackCustomizer loopCustomizer; + + @Override + public void setUp() throws Exception { + InterfaceTypeTestUtils.setupWriteContext(writeContext, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Loopback.class); + loopCustomizer = new LoopbackCustomizer(api, new NamingContext("ifcintest", IFC_TEST_INSTANCE)); + } + + @Test + public void testCreate() throws Exception { + doAnswer(new Answer() { + + int idx = 0; + + @Override + public Object answer(final InvocationOnMock invocation) throws Throwable { + final CreateLoopbackReply t = new CreateLoopbackReply(); + t.swIfIndex = idx++; + return future(t); + } + }).when(api).createLoopback(any(CreateLoopback.class)); + + loopCustomizer.writeCurrentAttributes(getLoopbackId("loop"), getLoopbackData("ff:ff:ff:ff:ff:ff"), writeContext); + loopCustomizer.writeCurrentAttributes(getLoopbackId("loop2"), getLoopbackData("ff:ff:ff:ff:ff:ff"), writeContext); + + verify(api, times(2)).createLoopback(any(CreateLoopback.class)); + verify(mappingContext).put(eq(mappingIid("loop", IFC_TEST_INSTANCE)), eq( + mapping("loop", 0).get())); + verify(mappingContext).put(eq(mappingIid("loop2", IFC_TEST_INSTANCE)), eq( + mapping("loop2", 1).get())); + } + + @Test + public void testDelete() throws Exception { + final CreateLoopbackReply t = new CreateLoopbackReply(); + t.swIfIndex = 0; + doReturn(future(t)).when(api).createLoopback(any(CreateLoopback.class)); + + doReturn(future(new DeleteLoopbackReply())).when(api).deleteLoopback(any(DeleteLoopback.class)); + + loopCustomizer.writeCurrentAttributes(getLoopbackId("loop"), getLoopbackData("ff:ff:ff:ff:ff:ff"), writeContext); + defineMapping(mappingContext, "loop", 1, IFC_TEST_INSTANCE); + loopCustomizer.deleteCurrentAttributes(getLoopbackId("loop"), getLoopbackData("ff:ff:ff:ff:ff:ff"), writeContext); + + verify(api).createLoopback(any(CreateLoopback.class)); + verify(api).deleteLoopback(any(DeleteLoopback.class)); + verify(mappingContext).delete(eq(mappingIid("loop", IFC_TEST_INSTANCE))); + } + + private InstanceIdentifier getLoopbackId(final String loop) { + return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(loop)).augmentation( + VppInterfaceAugmentation.class).child(Loopback.class); + } + + private Loopback getLoopbackData(final String mac) { + return new LoopbackBuilder().setMac(new PhysAddress(mac)).build(); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizerTest.java new file mode 100644 index 000000000..232d62e9e --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizerTest.java @@ -0,0 +1,97 @@ +/* + * 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; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +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.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArpBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.ProxyArpAddDel; +import io.fd.vpp.jvpp.core.dto.ProxyArpAddDelReply; + +public class ProxyArpCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { + private static final String IF_NAME = "eth1"; + + private ProxyArpCustomizer customizer; + + @Override + public void setUp() throws Exception { + customizer = new ProxyArpCustomizer(api); + } + + @Test + public void testWrite() throws WriteFailedException { + when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply())); + customizer.writeCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); + verify(api).proxyArpAddDel(expectedRequest(true)); + } + + @Test(expected = WriteFailedException.class) + public void testWriteFailed() throws WriteFailedException { + when(api.proxyArpAddDel(any())).thenReturn(failedFuture()); + customizer.writeCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); + } + + @Test(expected = WriteFailedException.UpdateFailedException.class) + public void testUpdate() throws WriteFailedException.UpdateFailedException { + customizer.updateCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), proxyArp(), writeContext); + } + + @Test + public void testDelete() throws WriteFailedException { + when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply())); + customizer.deleteCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); + verify(api).proxyArpAddDel(expectedRequest(false)); + } + + @Test(expected = WriteFailedException.DeleteFailedException.class) + public void testDeleteFailed() throws WriteFailedException { + when(api.proxyArpAddDel(any())).thenReturn(failedFuture()); + customizer.deleteCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); + } + + private ProxyArp proxyArp() { + return new ProxyArpBuilder().setVrfId(123L).setHighAddr(new Ipv4AddressNoZone("10.1.1.2")) + .setLowAddr(new Ipv4AddressNoZone("10.1.1.1")).build(); + } + + private ProxyArpAddDel expectedRequest(final boolean isAdd) { + final ProxyArpAddDel request = new ProxyArpAddDel(); + request.isAdd = booleanToByte(isAdd); + request.vrfId = 123; + request.lowAddress = new byte[]{10,1,1,1}; + request.hiAddress = new byte[]{10,1,1,2}; + return request; + } + + private InstanceIdentifier getProxyArpId(final String eth0) { + return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(eth0)).augmentation( + VppInterfaceAugmentation.class).child(ProxyArp.class); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizerTest.java new file mode 100644 index 000000000..fa9914233 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizerTest.java @@ -0,0 +1,198 @@ +/* + * 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; + +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.translate.util.TagRewriteOperation; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.L2InterfaceVlanTagRewrite; +import io.fd.vpp.jvpp.core.dto.L2InterfaceVlanTagRewriteReply; +import org.junit.Assert; +import org.junit.Test; +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.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1q; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.RewriteBuilder; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class RewriteCustomizerTest extends WriterCustomizerTest { + + private NamingContext namingContext; + private RewriteCustomizer customizer; + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final String VLAN_IF_NAME = "local0.1"; + private static final int VLAN_IF_ID = 1; + private static final int VLAN_IF_INDEX = 11; + private InstanceIdentifier VLAN_IID; + + @Override + public void setUp() throws Exception { + namingContext = new NamingContext("generatedSubInterfaceName", IFC_TEST_INSTANCE); + customizer = new RewriteCustomizer(api, namingContext); + VLAN_IID = getVlanTagRewriteId(IF_NAME, VLAN_IF_ID); + defineMapping(mappingContext, VLAN_IF_NAME, VLAN_IF_INDEX, IFC_TEST_INSTANCE); + } + + private static InstanceIdentifier getVlanTagRewriteId(final String name, final long index) { + final Class> child = (Class) Rewrite.class; + final InstanceIdentifier id = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(index)) + .child(child); + return id; + } + + private Rewrite generateRewrite(final TagRewriteOperation op) { + final RewriteBuilder builder = new RewriteBuilder(); + builder.setPopTags((short) op.getPopTags()); + builder.setVlanType(_802dot1q.class); + return builder.build(); + } + + private L2InterfaceVlanTagRewrite generateL2InterfaceVlanTagRewrite(final int swIfIndex, + final TagRewriteOperation op) { + final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite(); + request.swIfIndex = swIfIndex; + request.vtrOp = op.ordinal(); + request.pushDot1Q = 1; + return request; + } + + /** + * Positive response + */ + private void whenL2InterfaceVlanTagRewriteThenSuccess() { + doReturn(future(new L2InterfaceVlanTagRewriteReply())).when(api) + .l2InterfaceVlanTagRewrite(any(L2InterfaceVlanTagRewrite.class)); + } + + /** + * Failure response send + */ + private void whenL2InterfaceVlanTagRewriteThenFailure() { + doReturn(failedFuture()).when(api).l2InterfaceVlanTagRewrite(any(L2InterfaceVlanTagRewrite.class)); + } + + private void verifyL2InterfaceVlanTagRewriteDeleteWasInvoked() throws VppInvocationException { + final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite(); + request.swIfIndex = VLAN_IF_INDEX; + verify(api).l2InterfaceVlanTagRewrite(request); + } + + @Test + public void testCreate() throws Exception { + final TagRewriteOperation op = TagRewriteOperation.pop_2; + final Rewrite vlanTagRewrite = generateRewrite(op); + + whenL2InterfaceVlanTagRewriteThenSuccess(); + + customizer.writeCurrentAttributes(VLAN_IID, vlanTagRewrite, writeContext); + + verify(api).l2InterfaceVlanTagRewrite(generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, op)); + } + + @Test + public void testCreateFailed() throws Exception { + final TagRewriteOperation op = TagRewriteOperation.pop_2; + final Rewrite vlanTagRewrite = generateRewrite(op); + + whenL2InterfaceVlanTagRewriteThenFailure(); + + try { + customizer.writeCurrentAttributes(VLAN_IID, vlanTagRewrite, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).l2InterfaceVlanTagRewrite(generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, op)); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testUpdate() throws Exception { + final Rewrite before = generateRewrite(TagRewriteOperation.pop_2); + final Rewrite after = generateRewrite(TagRewriteOperation.pop_1); + + whenL2InterfaceVlanTagRewriteThenSuccess(); + + customizer.updateCurrentAttributes(VLAN_IID, before, after, writeContext); + + verify(api) + .l2InterfaceVlanTagRewrite(generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, TagRewriteOperation.pop_1)); + } + + @Test + public void testUpdateFailed() throws Exception { + final Rewrite before = generateRewrite(TagRewriteOperation.pop_2); + final Rewrite after = generateRewrite(TagRewriteOperation.pop_1); + + whenL2InterfaceVlanTagRewriteThenFailure(); + + try { + customizer.updateCurrentAttributes(VLAN_IID, before, after, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api) + .l2InterfaceVlanTagRewrite( + generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, TagRewriteOperation.pop_1)); + return; + } + fail("WriteFailedException.UpdateFailedException was expected"); + } + + @Test + public void testDelete() throws Exception { + whenL2InterfaceVlanTagRewriteThenSuccess(); + + customizer.deleteCurrentAttributes(VLAN_IID, null, writeContext); + + verifyL2InterfaceVlanTagRewriteDeleteWasInvoked(); + } + + @Test + public void testDeleteFailed() throws Exception { + whenL2InterfaceVlanTagRewriteThenFailure(); + + try { + customizer.deleteCurrentAttributes(VLAN_IID, null, writeContext); + } catch (WriteFailedException e) { + Assert.assertTrue(e.getCause() instanceof VppBaseCallException); + verifyL2InterfaceVlanTagRewriteDeleteWasInvoked(); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/RoutingCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/RoutingCustomizerTest.java new file mode 100644 index 000000000..a61cd149b --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/RoutingCustomizerTest.java @@ -0,0 +1,97 @@ +/* + * 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; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetTable; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetTableReply; +import org.junit.Test; +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.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Routing; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.RoutingBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class RoutingCustomizerTest extends WriterCustomizerTest { + private static final String IFACE_CTX_NAME = "interface-ctx"; + private static final String IF_NAME = "eth1"; + private static final int IF_INDEX = 1; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(Routing.class); + + private RoutingCustomizer customizer; + + @Override + protected void setUp() throws Exception { + customizer = new RoutingCustomizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME); + } + + @Test + public void testWrite() throws WriteFailedException { + final int vrfId = 123; + when(api.swInterfaceSetTable(any())).thenReturn(future(new SwInterfaceSetTableReply())); + customizer.writeCurrentAttributes(IID, routing(vrfId), writeContext); + verify(api).swInterfaceSetTable(expectedRequest(vrfId)); + } + + @Test(expected = WriteFailedException.class) + public void testWriteFailed() throws WriteFailedException { + when(api.swInterfaceSetTable(any())).thenReturn(failedFuture()); + customizer.writeCurrentAttributes(IID, routing(213), writeContext); + } + + @Test(expected = WriteFailedException.class) + public void testUpdateFailed() throws WriteFailedException { + when(api.swInterfaceSetTable(any())).thenReturn(failedFuture()); + customizer.updateCurrentAttributes(IID, routing(123L), routing(321L), writeContext); + } + + @Test + public void testDelete() throws WriteFailedException { + when(api.swInterfaceSetTable(any())).thenReturn(future(new SwInterfaceSetTableReply())); + customizer.deleteCurrentAttributes(IID, routing(123), writeContext); + verify(api).swInterfaceSetTable(expectedRequest(0)); + } + + @Test(expected = WriteFailedException.DeleteFailedException.class) + public void testDeleteFailed() throws WriteFailedException { + when(api.swInterfaceSetTable(any())).thenReturn(failedFuture()); + customizer.deleteCurrentAttributes(IID, routing(123), writeContext); + } + + private Routing routing(final long vrfId) { + return new RoutingBuilder().setIpv4VrfId(vrfId).build(); + } + + private SwInterfaceSetTable expectedRequest(final int vrfId) { + final SwInterfaceSetTable request = new SwInterfaceSetTable(); + request.isIpv6 = 0; + request.swIfIndex = IF_INDEX; + request.vrfId = vrfId; + return request; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizerTest.java new file mode 100644 index 000000000..fd71a8015 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizerTest.java @@ -0,0 +1,258 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import java.util.Arrays; +import java.util.List; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qTagVlanType; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId; +import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan; +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.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTagBuilder; +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.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1ad; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTaggedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.TagsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.CreateSubif; +import io.fd.vpp.jvpp.core.dto.CreateSubifReply; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlags; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsReply; + +public class SubInterfaceCustomizerTest extends WriterCustomizerTest { + + private NamingContext namingContext; + private SubInterfaceCustomizer customizer; + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String SUPER_IF_NAME = "local0"; + private static final int SUPER_IF_ID = 1; + private static final String SUB_IFACE_NAME = "local0.11"; + private static final int SUBIF_INDEX = 11; + + private static final short STAG_ID = 100; + private static final short CTAG_ID = 200; + private static final short CTAG_ANY_ID = 0; // only the *IdAny flag is set + + private final Tag STAG_100; + private final Tag CTAG_200; + private final Tag CTAG_ANY; + + public SubInterfaceCustomizerTest() { + STAG_100 = generateTag((short) 0, SVlan.class, new Dot1qTag.VlanId(new Dot1qVlanId((int) STAG_ID))); + CTAG_200 = generateTag((short) 1, CVlan.class, new Dot1qTag.VlanId(new Dot1qVlanId(200))); + CTAG_ANY = generateTag((short) 1, CVlan.class, new Dot1qTag.VlanId(Dot1qTag.VlanId.Enumeration.Any)); + } + + @Override + public void setUp() throws Exception { + namingContext = new NamingContext("generatedSubInterfaceName", IFC_TEST_INSTANCE); + customizer = new SubInterfaceCustomizer(api, namingContext); + defineMapping(mappingContext, SUB_IFACE_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); + defineMapping(mappingContext, SUPER_IF_NAME, SUPER_IF_ID, IFC_TEST_INSTANCE); + } + + private SubInterface generateSubInterface(final boolean enabled, final List tagList) { + SubInterfaceBuilder builder = new SubInterfaceBuilder(); + builder.setVlanType(_802dot1ad.class); + builder.setIdentifier(11L); + final TagsBuilder tags = new TagsBuilder(); + + tags.setTag(tagList); + + builder.setTags(tags.build()); + + builder.setMatch(generateMatch()); + builder.setEnabled(enabled); + return builder.build(); + } + + private static Tag generateTag(final short index, final Class tagType, + final Dot1qTag.VlanId vlanId) { + TagBuilder tag = new TagBuilder(); + tag.setIndex(index); + tag.setKey(new TagKey(index)); + final Dot1qTagBuilder dtag = new Dot1qTagBuilder(); + dtag.setTagType(tagType); + dtag.setVlanId(vlanId); + tag.setDot1qTag(dtag.build()); + return tag.build(); + } + + private static Match generateMatch() { + final MatchBuilder match = new MatchBuilder(); + final VlanTaggedBuilder tagged = new VlanTaggedBuilder(); + tagged.setMatchExactTags(true); + match.setMatchType( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.VlanTaggedBuilder() + .setVlanTagged(tagged.build()).build()); + return match.build(); + } + + private CreateSubif generateSubInterfaceRequest(final int superIfId, final short innerVlanId, + final boolean isInnerAny) { + CreateSubif request = new CreateSubif(); + request.subId = 11; + request.swIfIndex = superIfId; + request.twoTags = 1; + request.innerVlanId = innerVlanId; + request.innerVlanIdAny = (byte) (isInnerAny + ? 1 + : 0); + request.dot1Ad = 1; + request.outerVlanId = STAG_ID; + return request; + } + + private SwInterfaceSetFlags generateSwInterfaceEnableRequest(final int swIfIndex) { + SwInterfaceSetFlags request = new SwInterfaceSetFlags(); + request.swIfIndex = swIfIndex; + request.adminUpDown = 1; + return request; + } + + private InstanceIdentifier getSubInterfaceId(final String name, final long index) { + return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(index)); + } + + private void whenCreateSubifThenSuccess() { + doReturn(future(new CreateSubifReply())).when(api).createSubif(any(CreateSubif.class)); + } + + /** + * Failure response send + */ + private void whenCreateSubifThenFailure() { + doReturn(failedFuture()).when(api).createSubif(any(CreateSubif.class)); + } + + private void whenSwInterfaceSetFlagsThenSuccess() { + doReturn(future(new SwInterfaceSetFlagsReply())).when(api).swInterfaceSetFlags(any(SwInterfaceSetFlags.class)); + } + + private SwInterfaceSetFlags verifySwInterfaceSetFlagsWasInvoked(final SwInterfaceSetFlags expected) + throws VppBaseCallException { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(SwInterfaceSetFlags.class); + verify(api).swInterfaceSetFlags(argumentCaptor.capture()); + final SwInterfaceSetFlags actual = argumentCaptor.getValue(); + + assertEquals(expected.swIfIndex, actual.swIfIndex); + assertEquals(expected.adminUpDown, actual.adminUpDown); + return actual; + } + + @Test + public void testCreateTwoTags() throws Exception { + final SubInterface subInterface = generateSubInterface(false, Arrays.asList(STAG_100, CTAG_200)); + final InstanceIdentifier id = getSubInterfaceId(SUPER_IF_NAME, SUBIF_INDEX); + + whenCreateSubifThenSuccess(); + whenSwInterfaceSetFlagsThenSuccess(); + + customizer.writeCurrentAttributes(id, subInterface, writeContext); + + verify(api).createSubif(generateSubInterfaceRequest(SUPER_IF_ID, CTAG_ID, false)); + verify(mappingContext) + .put(eq(mappingIid(SUB_IFACE_NAME, IFC_TEST_INSTANCE)), eq( + mapping(SUB_IFACE_NAME, 0).get())); + } + + @Test + public void testCreateDot1qAnyTag() throws Exception { + final SubInterface subInterface = generateSubInterface(false, Arrays.asList(STAG_100, CTAG_ANY)); + final InstanceIdentifier id = getSubInterfaceId(SUPER_IF_NAME, SUBIF_INDEX); + + whenCreateSubifThenSuccess(); + whenSwInterfaceSetFlagsThenSuccess(); + + customizer.writeCurrentAttributes(id, subInterface, writeContext); + + verify(api).createSubif(generateSubInterfaceRequest(SUPER_IF_ID, CTAG_ANY_ID, true)); + verify(mappingContext) + .put(eq(mappingIid(SUB_IFACE_NAME, IFC_TEST_INSTANCE)), eq( + mapping(SUB_IFACE_NAME, 0).get())); + } + + @Test + public void testCreateFailed() throws Exception { + final SubInterface subInterface = generateSubInterface(false, Arrays.asList(STAG_100, CTAG_200)); + final InstanceIdentifier id = getSubInterfaceId(SUPER_IF_NAME, SUBIF_INDEX); + + whenCreateSubifThenFailure(); + + try { + customizer.writeCurrentAttributes(id, subInterface, writeContext); + } catch (WriteFailedException.CreateFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).createSubif(generateSubInterfaceRequest(SUPER_IF_ID, CTAG_ID, false)); + verify(mappingContext, times(0)).put( + eq(mappingIid(SUPER_IF_NAME, IFC_TEST_INSTANCE)), + eq(mapping(SUPER_IF_NAME, 0).get())); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testUpdate() throws Exception { + final List tags = Arrays.asList(STAG_100, CTAG_200); + final SubInterface before = generateSubInterface(false, tags); + final SubInterface after = generateSubInterface(true, tags); + final InstanceIdentifier id = getSubInterfaceId(SUPER_IF_NAME, SUBIF_INDEX); + + whenSwInterfaceSetFlagsThenSuccess(); + customizer.updateCurrentAttributes(id, before, after, writeContext); + + verifySwInterfaceSetFlagsWasInvoked(generateSwInterfaceEnableRequest(SUBIF_INDEX)); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDelete() throws Exception { + final SubInterface subInterface = generateSubInterface(false, Arrays.asList(STAG_100, CTAG_200)); + customizer.deleteCurrentAttributes(null, subInterface, writeContext); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2CustomizerTest.java new file mode 100644 index 000000000..29b1b0d99 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2CustomizerTest.java @@ -0,0 +1,109 @@ +/* + * 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; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +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.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Bridge; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2BridgeReply; + +public class SubInterfaceL2CustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { + private static final String IFACE_CTX_NAME = "interface-ctx"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUBIF_NAME = "local0.0"; + private static final int SUBIF_INDEX = 11; + private static final long SUBIF_ID = 0; + + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(L2.class); + + + private static final String BD_CTX_NAME = "bd-ctx"; + private static final String BD_NAME = "test_bd"; + private static final int BD_INDEX = 13; + + private SubInterfaceL2Customizer customizer; + + @Override + protected void setUp() throws Exception { + customizer = new SubInterfaceL2Customizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME), + new NamingContext("bdPrefix", BD_CTX_NAME)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFACE_CTX_NAME); + defineMapping(mappingContext, BD_NAME, BD_INDEX, BD_CTX_NAME); + } + + @Test + public void testWrite() throws WriteFailedException { + final boolean bvi = true; + when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply())); + customizer.writeCurrentAttributes(IID, l2(bvi), writeContext); + verify(api).swInterfaceSetL2Bridge(bridgeRequest(bvi, true)); + } + + @Test + public void testUpdate() throws WriteFailedException { + final boolean bvi = false; + when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply())); + customizer.updateCurrentAttributes(IID, l2(true), l2(bvi), writeContext); + verify(api).swInterfaceSetL2Bridge(bridgeRequest(bvi, true)); + } + + @Test + public void testDelete() throws WriteFailedException { + final boolean bvi = true; + when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply())); + customizer.deleteCurrentAttributes(IID, l2(bvi), writeContext); + verify(api).swInterfaceSetL2Bridge(bridgeRequest(bvi, false)); + } + + private L2 l2(final boolean bvi) { + return new L2Builder().setInterconnection(new BridgeBasedBuilder().setBridgedVirtualInterface(bvi) + .setBridgeDomain(BD_NAME).setSplitHorizonGroup((short) 123).build()).build(); + } + + private SwInterfaceSetL2Bridge bridgeRequest(final boolean bvi, final boolean enable) { + final SwInterfaceSetL2Bridge request = new SwInterfaceSetL2Bridge(); + request.bdId = BD_INDEX; + request.rxSwIfIndex = SUBIF_INDEX; + request.bvi = booleanToByte(bvi); + request.enable = booleanToByte(enable); + request.shg = 123; + return request; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/TapCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/TapCustomizerTest.java new file mode 100644 index 000000000..f55859ace --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/TapCustomizerTest.java @@ -0,0 +1,129 @@ +/* + * 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; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +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.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.TapBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.TapConnect; +import io.fd.vpp.jvpp.core.dto.TapConnectReply; +import io.fd.vpp.jvpp.core.dto.TapDelete; +import io.fd.vpp.jvpp.core.dto.TapDeleteReply; +import io.fd.vpp.jvpp.core.dto.TapModify; +import io.fd.vpp.jvpp.core.dto.TapModifyReply; + +public class TapCustomizerTest extends WriterCustomizerTest { + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private TapCustomizer tapCustomizer; + + @Override + public void setUp() throws Exception { + InterfaceTypeTestUtils.setupWriteContext(writeContext, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap.class); + tapCustomizer = new TapCustomizer(api, new NamingContext("ifcintest", IFC_TEST_INSTANCE)); + } + + @Test + public void testCreate() throws Exception { + doAnswer(new Answer() { + + int idx = 0; + + @Override + public Object answer(final InvocationOnMock invocation) throws Throwable { + final TapConnectReply t = new TapConnectReply(); + t.swIfIndex = idx++; + return future(t); + } + }).when(api).tapConnect(any(TapConnect.class)); + + tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext); + tapCustomizer.writeCurrentAttributes(getTapId("tap2"), getTapData("tap2", "ff:ff:ff:ff:ff:ff"), writeContext); + + verify(api, times(2)).tapConnect(any(TapConnect.class)); + verify(mappingContext).put(eq(mappingIid("tap", IFC_TEST_INSTANCE)), eq( + mapping("tap", 0).get())); + verify(mappingContext).put(eq(mappingIid("tap2", IFC_TEST_INSTANCE)), eq( + mapping("tap2", 1).get())); + } + + @Test + public void testModify() throws Exception { + final TapConnectReply t = new TapConnectReply(); + t.swIfIndex = 0; + doReturn(future(t)).when(api).tapConnect(any(TapConnect.class)); + + final TapModifyReply tmodif = new TapModifyReply(); + tmodif.swIfIndex = 0; + doReturn(future(tmodif)).when(api).tapModify(any(TapModify.class)); + + tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext); + + defineMapping(mappingContext, "tap", 1, IFC_TEST_INSTANCE); + tapCustomizer.updateCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), getTapData("tap", "ff:ff:ff:ff:ff:f1"), writeContext); + + verify(api).tapConnect(any(TapConnect.class)); + verify(api).tapModify(any(TapModify.class)); + + verify(mappingContext).put(eq(mappingIid("tap", IFC_TEST_INSTANCE)), eq( + mapping("tap", 0).get())); + } + + @Test + public void testDelete() throws Exception { + final TapConnectReply t = new TapConnectReply(); + t.swIfIndex = 0; + doReturn(future(t)).when(api).tapConnect(any(TapConnect.class)); + + doReturn(future(new TapDeleteReply())).when(api).tapDelete(any(TapDelete.class)); + + tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext); + defineMapping(mappingContext, "tap", 1, IFC_TEST_INSTANCE); + tapCustomizer.deleteCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext); + + verify(api).tapConnect(any(TapConnect.class)); + verify(api).tapDelete(any(TapDelete.class)); + verify(mappingContext).delete(eq(mappingIid("tap", IFC_TEST_INSTANCE))); + } + + private InstanceIdentifier getTapId(final String tap) { + return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(tap)).augmentation( + VppInterfaceAugmentation.class).child(Tap.class); + } + + private Tap getTapData(final String tap, final String mac) { + return new TapBuilder().setTapName(tap).setMac(new PhysAddress(mac)).build(); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizerTest.java new file mode 100644 index 000000000..4f8b7a6d4 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizerTest.java @@ -0,0 +1,205 @@ +/* + * 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; + +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.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +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.rev161214.VhostUserRole; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUserBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.CreateVhostUserIf; +import io.fd.vpp.jvpp.core.dto.CreateVhostUserIfReply; +import io.fd.vpp.jvpp.core.dto.DeleteVhostUserIf; +import io.fd.vpp.jvpp.core.dto.DeleteVhostUserIfReply; +import io.fd.vpp.jvpp.core.dto.ModifyVhostUserIf; +import io.fd.vpp.jvpp.core.dto.ModifyVhostUserIfReply; + +public class VhostUserCustomizerTest extends WriterCustomizerTest implements Ipv4Translator { + + private VhostUserCustomizer customizer; + private static final int IFACE_ID = 1; + private static final String IFACE_NAME = "eth0"; + private static final InstanceIdentifier ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(VhostUser.class); + + @Override + public void setUp() throws Exception { + InterfaceTypeTestUtils.setupWriteContext(writeContext, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser.class); + customizer = new VhostUserCustomizer(api, new NamingContext("generatedInterfaceName", "test-instance")); + } + + private CreateVhostUserIf verifyCreateVhostUserIfWasInvoked(final VhostUser vhostUser) + throws VppInvocationException { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CreateVhostUserIf.class); + verify(api).createVhostUserIf(argumentCaptor.capture()); + final CreateVhostUserIf actual = argumentCaptor.getValue(); + assertEquals(0, actual.customDevInstance); + + assertEquals(booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer); + assertEquals(0, actual.renumber); + assertEquals(0, actual.useCustomMac); + assertArrayEquals(vhostUser.getSocket().getBytes(), actual.sockFilename); + assertNotNull(actual.macAddress); + return actual; + } + + private ModifyVhostUserIf verifyModifyVhostUserIfWasInvoked(final VhostUser vhostUser, final int swIfIndex) + throws VppInvocationException { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(ModifyVhostUserIf.class); + verify(api).modifyVhostUserIf(argumentCaptor.capture()); + final ModifyVhostUserIf actual = argumentCaptor.getValue(); + assertEquals(0, actual.customDevInstance); + + assertEquals(booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer); + assertEquals(0, actual.renumber); + assertEquals(swIfIndex, actual.swIfIndex); + assertArrayEquals(vhostUser.getSocket().getBytes(), actual.sockFilename); + return actual; + } + + private DeleteVhostUserIf verifyDeleteVhostUserIfWasInvoked(final int swIfIndex) throws VppInvocationException { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(DeleteVhostUserIf.class); + verify(api).deleteVhostUserIf(argumentCaptor.capture()); + final DeleteVhostUserIf actual = argumentCaptor.getValue(); + assertEquals(swIfIndex, actual.swIfIndex); + return actual; + } + + private static VhostUser generateVhostUser(final VhostUserRole role, final String socketName) { + VhostUserBuilder builder = new VhostUserBuilder(); + builder.setRole(role); + builder.setSocket(socketName); + return builder.build(); + } + + @Test + public void testWriteCurrentAttributes() throws Exception { + final VhostUser vhostUser = generateVhostUser(VhostUserRole.Server, "socketName"); + + when(api.createVhostUserIf(any(CreateVhostUserIf.class))).thenReturn(future(new CreateVhostUserIfReply())); + + customizer.writeCurrentAttributes(ID, vhostUser, writeContext); + verifyCreateVhostUserIfWasInvoked(vhostUser); + verify(mappingContext).put(eq(mappingIid(IFACE_NAME, "test-instance")), eq( + mapping(IFACE_NAME, 0).get())); + } + + @Test + public void testWriteCurrentAttributesFailed() throws Exception { + final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName"); + + doReturn(failedFuture()).when(api).createVhostUserIf(any(CreateVhostUserIf.class)); + + try { + customizer.writeCurrentAttributes(ID, vhostUser, writeContext); + } catch (WriteFailedException.CreateFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyCreateVhostUserIfWasInvoked(vhostUser); + verifyZeroInteractions(mappingContext); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testUpdateCurrentAttributes() throws Exception { + final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Client, "socketName0"); + final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName1"); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, "test-instance"); + + when(api.modifyVhostUserIf(any(ModifyVhostUserIf.class))).thenReturn(future(new ModifyVhostUserIfReply())); + + customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext); + verifyModifyVhostUserIfWasInvoked(vhostUserAfter, IFACE_ID); + } + + @Test + public void testUpdateCurrentAttributesFailed() throws Exception { + final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Client, "socketName0"); + final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName1"); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, "test-instance"); + + doReturn(failedFuture()).when(api).modifyVhostUserIf(any(ModifyVhostUserIf.class)); + + try { + customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext); + } catch (WriteFailedException.UpdateFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyModifyVhostUserIfWasInvoked(vhostUserAfter, IFACE_ID); + return; + } + fail("WriteFailedException.UpdateFailedException was expected"); + } + + @Test + public void testDeleteCurrentAttributes() throws Exception { + final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName"); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, "test-instance"); + + when(api.deleteVhostUserIf(any(DeleteVhostUserIf.class))).thenReturn(future(new DeleteVhostUserIfReply())); + + customizer.deleteCurrentAttributes(ID, vhostUser, writeContext); + verifyDeleteVhostUserIfWasInvoked(IFACE_ID); + verify(mappingContext).delete(eq(mappingIid(IFACE_NAME, "test-instance"))); + } + + @Test + public void testDeleteCurrentAttributesFailed() throws Exception { + final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName"); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, "test-instance"); + + doReturn(failedFuture()).when(api).deleteVhostUserIf(any(DeleteVhostUserIf.class)); + + try { + customizer.deleteCurrentAttributes(ID, vhostUser, writeContext); + } catch (WriteFailedException.DeleteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyDeleteVhostUserIfWasInvoked(IFACE_ID); + // Delete from context not invoked if delete from VPP failed + verify(mappingContext, times(0)).delete(eq(mappingIid(IFACE_NAME, "test-instance"))); + verify(mappingContext).read(eq(mappingIid(IFACE_NAME, "test-instance"))); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizerTest.java new file mode 100644 index 000000000..f5b6873de --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizerTest.java @@ -0,0 +1,227 @@ +/* + * 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; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.net.InetAddresses; +import io.fd.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.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.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanVni; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.VxlanAddDelTunnel; +import io.fd.vpp.jvpp.core.dto.VxlanAddDelTunnelReply; + +public class VxlanCustomizerTest extends WriterCustomizerTest { + + private static final byte ADD_VXLAN = 1; + private static final byte DEL_VXLAN = 0; + + @Mock + private DisabledInterfacesManager disableContext; + + private VxlanCustomizer customizer; + private String ifaceName; + private InstanceIdentifier id; + + @Override + public void setUp() throws Exception { + InterfaceTypeTestUtils.setupWriteContext(writeContext, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel.class); + + customizer = + new VxlanCustomizer(api, new NamingContext("generateInterfaceNAme", "test-instance"), disableContext); + + ifaceName = "eth0"; + id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(ifaceName)) + .augmentation(VppInterfaceAugmentation.class).child(Vxlan.class); + } + + private void whenVxlanAddDelTunnelThenSuccess() { + when(api.vxlanAddDelTunnel(any(VxlanAddDelTunnel.class))).thenReturn(future(new VxlanAddDelTunnelReply())); + } + + private void whenVxlanAddDelTunnelThenFailure() { + doReturn(failedFuture()).when(api).vxlanAddDelTunnel(any(VxlanAddDelTunnel.class)); + } + + private VxlanAddDelTunnel verifyVxlanAddDelTunnelWasInvoked(final Vxlan vxlan) throws VppInvocationException { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(VxlanAddDelTunnel.class); + verify(api).vxlanAddDelTunnel(argumentCaptor.capture()); + final VxlanAddDelTunnel actual = argumentCaptor.getValue(); + assertEquals(0, actual.isIpv6); + assertEquals(-1, actual.decapNextIndex); + assertArrayEquals(InetAddresses.forString(vxlan.getSrc().getIpv4Address().getValue()).getAddress(), + actual.srcAddress); + assertArrayEquals(InetAddresses.forString(vxlan.getDst().getIpv4Address().getValue()).getAddress(), + actual.dstAddress); + assertEquals(vxlan.getEncapVrfId().intValue(), actual.encapVrfId); + assertEquals(vxlan.getVni().getValue().intValue(), actual.vni); + return actual; + } + + private void verifyVxlanAddWasInvoked(final Vxlan vxlan) throws VppInvocationException { + final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan); + assertEquals(ADD_VXLAN, actual.isAdd); + } + + private void verifyVxlanDeleteWasInvoked(final Vxlan vxlan) throws VppInvocationException { + final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan); + assertEquals(DEL_VXLAN, actual.isAdd); + } + + private static Vxlan generateVxlan(long vni) { + final VxlanBuilder builder = new VxlanBuilder(); + builder.setSrc(new IpAddress(new Ipv4Address("192.168.20.10"))); + builder.setDst(new IpAddress(new Ipv4Address("192.168.20.11"))); + builder.setEncapVrfId(Long.valueOf(123)); + builder.setVni(new VxlanVni(Long.valueOf(vni))); + return builder.build(); + } + + private static Vxlan generateVxlan() { + return generateVxlan(Long.valueOf(11)); + } + + @Test + public void testWriteCurrentAttributes() throws Exception { + final Vxlan vxlan = generateVxlan(); + + whenVxlanAddDelTunnelThenSuccess(); + noMappingDefined(mappingContext, ifaceName, "test-instance"); + + customizer.writeCurrentAttributes(id, vxlan, writeContext); + verifyVxlanAddWasInvoked(vxlan); + verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, 0).get())); + } + + @Test + public void testWriteCurrentAttributesWithExistingVxlanPlaceholder() throws Exception { + final Vxlan vxlan = generateVxlan(); + + whenVxlanAddDelTunnelThenSuccess(); + noMappingDefined(mappingContext, ifaceName, "test-instance"); + doReturn(true).when(disableContext).isInterfaceDisabled(0, mappingContext); + + customizer.writeCurrentAttributes(id, vxlan, writeContext); + verifyVxlanAddWasInvoked(vxlan); + verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, 0).get())); + verify(disableContext).removeDisabledInterface(0, mappingContext); + } + + @Test + public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception { + final Vxlan vxlan = generateVxlan(); + final int ifaceId = 0; + + whenVxlanAddDelTunnelThenSuccess(); + defineMapping(mappingContext, ifaceName, ifaceId, "test-instance"); + + customizer.writeCurrentAttributes(id, vxlan, writeContext); + verifyVxlanAddWasInvoked(vxlan); + + // Remove the first mapping before putting in the new one + verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance"))); + verify(mappingContext) + .put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, ifaceId).get())); + } + + @Test + public void testWriteCurrentAttributesFailed() throws Exception { + final Vxlan vxlan = generateVxlan(); + + whenVxlanAddDelTunnelThenFailure(); + + try { + customizer.writeCurrentAttributes(id, vxlan, writeContext); + } catch (WriteFailedException.CreateFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyVxlanAddWasInvoked(vxlan); + // Mapping not stored due to failure + verify(mappingContext, times(0)) + .put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, 0).get())); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testUpdateCurrentAttributes() throws Exception { + try { + customizer.updateCurrentAttributes(id, generateVxlan(10), generateVxlan(11), writeContext); + } catch (WriteFailedException.UpdateFailedException e) { + assertEquals(UnsupportedOperationException.class, e.getCause().getClass()); + return; + } + fail("WriteFailedException.UpdateFailedException was expected"); + } + + @Test + public void testDeleteCurrentAttributes() throws Exception { + final Vxlan vxlan = generateVxlan(); + + whenVxlanAddDelTunnelThenSuccess(); + defineMapping(mappingContext, ifaceName, 1, "test-instance"); + + customizer.deleteCurrentAttributes(id, vxlan, writeContext); + verifyVxlanDeleteWasInvoked(vxlan); + verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance"))); + verify(disableContext).disableInterface(1, mappingContext); + } + + @Test + public void testDeleteCurrentAttributesaFailed() throws Exception { + final Vxlan vxlan = generateVxlan(); + + whenVxlanAddDelTunnelThenFailure(); + defineMapping(mappingContext, ifaceName, 1, "test-instance"); + + try { + customizer.deleteCurrentAttributes(id, vxlan, writeContext); + } catch (WriteFailedException.DeleteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyVxlanDeleteWasInvoked(vxlan); + verify(mappingContext, times(0)).delete(eq(mappingIid(ifaceName, "test-instance"))); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizerTest.java new file mode 100644 index 000000000..7337c16e3 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizerTest.java @@ -0,0 +1,218 @@ +/* + * 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; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.net.InetAddresses; +import io.fd.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.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.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeNextProtocol; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeVni; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpeBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.VxlanGpeAddDelTunnel; +import io.fd.vpp.jvpp.core.dto.VxlanGpeAddDelTunnelReply; + +public class VxlanGpeCustomizerTest extends WriterCustomizerTest { + + private static final byte ADD_VXLAN_GPE = 1; + private static final byte DEL_VXLAN_GPE = 0; + + @Mock + private DisabledInterfacesManager interfaceDisableContext; + + private VxlanGpeCustomizer customizer; + private String ifaceName; + private InstanceIdentifier id; + + @Override + public void setUp() throws Exception { + InterfaceTypeTestUtils.setupWriteContext(writeContext, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel.class); + NamingContext namingContext = new NamingContext("generateInterfaceName", "test-instance"); + customizer = new VxlanGpeCustomizer(api, namingContext, interfaceDisableContext); + + ifaceName = "elth0"; + id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(ifaceName)) + .augmentation(VppInterfaceAugmentation.class).child(VxlanGpe.class); + } + + private void whenVxlanGpeAddDelTunnelThenSuccess() { + when(api.vxlanGpeAddDelTunnel(any(VxlanGpeAddDelTunnel.class))) + .thenReturn(future(new VxlanGpeAddDelTunnelReply())); + } + + private void whenVxlanGpeAddDelTunnelThenFailure() { + doReturn(failedFuture()).when(api).vxlanGpeAddDelTunnel(any(VxlanGpeAddDelTunnel.class)); + } + + private VxlanGpeAddDelTunnel verifyVxlanGpeAddDelTunnelWasInvoked(final VxlanGpe vxlanGpe) + throws VppBaseCallException { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(VxlanGpeAddDelTunnel.class); + verify(api).vxlanGpeAddDelTunnel(argumentCaptor.capture()); + final VxlanGpeAddDelTunnel actual = argumentCaptor.getValue(); + assertEquals(0, actual.isIpv6); + assertArrayEquals(InetAddresses.forString(vxlanGpe.getLocal().getIpv4Address().getValue()).getAddress(), + actual.local); + assertArrayEquals(InetAddresses.forString(vxlanGpe.getRemote().getIpv4Address().getValue()).getAddress(), + actual.remote); + assertEquals(vxlanGpe.getVni().getValue().intValue(), actual.vni); + assertEquals(vxlanGpe.getNextProtocol().getIntValue(), actual.protocol); + assertEquals(vxlanGpe.getEncapVrfId().intValue(), actual.encapVrfId); + assertEquals(vxlanGpe.getDecapVrfId().intValue(), actual.decapVrfId); + return actual; + } + + private void verifyVxlanGpeAddWasInvoked(final VxlanGpe vxlanGpe) throws VppBaseCallException { + final VxlanGpeAddDelTunnel actual = verifyVxlanGpeAddDelTunnelWasInvoked(vxlanGpe); + assertEquals(ADD_VXLAN_GPE, actual.isAdd); + } + + private void verifyVxlanGpeDeleteWasInvoked(final VxlanGpe vxlanGpe) throws VppBaseCallException { + final VxlanGpeAddDelTunnel actual = verifyVxlanGpeAddDelTunnelWasInvoked(vxlanGpe); + assertEquals(DEL_VXLAN_GPE, actual.isAdd); + } + + private static VxlanGpe generateVxlanGpe(long vni) { + final VxlanGpeBuilder builder = new VxlanGpeBuilder(); + builder.setLocal(new IpAddress(new Ipv4Address("192.168.20.10"))); + builder.setRemote(new IpAddress(new Ipv4Address("192.168.20.11"))); + builder.setVni(new VxlanGpeVni(Long.valueOf(vni))); + builder.setNextProtocol(VxlanGpeNextProtocol.forValue(1)); + builder.setEncapVrfId(Long.valueOf(123)); + builder.setDecapVrfId(Long.valueOf(456)); + return builder.build(); + } + + private static VxlanGpe generateVxlanGpe() { + return generateVxlanGpe(Long.valueOf(11)); + } + + @Test + public void testWriteCurrentAttributes() throws Exception { + final VxlanGpe vxlanGpe = generateVxlanGpe(); + + whenVxlanGpeAddDelTunnelThenSuccess(); + noMappingDefined(mappingContext, ifaceName, "test-instance"); + + customizer.writeCurrentAttributes(id, vxlanGpe, writeContext); + verifyVxlanGpeAddWasInvoked(vxlanGpe); + verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), eq( + mapping(ifaceName, 0).get())); + } + + @Test + public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception { + final VxlanGpe vxlanGpe = generateVxlanGpe(); + final int ifaceId = 0; + + whenVxlanGpeAddDelTunnelThenSuccess(); + defineMapping(mappingContext, ifaceName, ifaceId, "test-instance"); + + customizer.writeCurrentAttributes(id, vxlanGpe, writeContext); + verifyVxlanGpeAddWasInvoked(vxlanGpe); + + // Remove the first mapping before putting in the new one + verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance"))); + verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), + eq(mapping(ifaceName, ifaceId).get())); + } + + @Test + public void testWriteCurrentAttributesFailed() throws Exception { + final VxlanGpe vxlanGpe = generateVxlanGpe(); + + whenVxlanGpeAddDelTunnelThenFailure(); + + try { + customizer.writeCurrentAttributes(id, vxlanGpe, writeContext); + } catch (WriteFailedException.CreateFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyVxlanGpeAddWasInvoked(vxlanGpe); + // Mapping not stored due to failure + verify(mappingContext, times(0)) + .put(eq(mappingIid(ifaceName, "test-instance")), eq( + mapping(ifaceName, 0).get())); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testUpdateCurrentAttributes() throws Exception { + try { + customizer.updateCurrentAttributes(id, generateVxlanGpe(10), generateVxlanGpe(11), writeContext); + } catch (WriteFailedException.UpdateFailedException e) { + assertEquals(UnsupportedOperationException.class, e.getCause().getClass()); + return; + } + fail("WriteFailedException.UpdateFailedException was expected"); + } + + @Test + public void testDeleteCurrentAttributes() throws Exception { + final VxlanGpe vxlanGpe = generateVxlanGpe(); + + whenVxlanGpeAddDelTunnelThenSuccess(); + defineMapping(mappingContext, ifaceName, 1, "test-instance"); + + customizer.deleteCurrentAttributes(id, vxlanGpe, writeContext); + verifyVxlanGpeDeleteWasInvoked(vxlanGpe); + verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance"))); + } + + @Test + public void testDeleteCurrentAttributesaFailed() throws Exception { + final VxlanGpe vxlanGpe = generateVxlanGpe(); + + whenVxlanGpeAddDelTunnelThenFailure(); + defineMapping(mappingContext, ifaceName, 1, "test-instance"); + + try { + customizer.deleteCurrentAttributes(id, vxlanGpe, writeContext); + } catch (WriteFailedException.DeleteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyVxlanGpeDeleteWasInvoked(vxlanGpe); + verify(mappingContext, times(0)).delete(eq(mappingIid(ifaceName, "test-instance"))); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/AclWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/AclWriterTest.java new file mode 100644 index 000000000..7641bd912 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/AclWriterTest.java @@ -0,0 +1,103 @@ +/* + * 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.acl; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import java.util.Collections; +import java.util.List; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; +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.InterfacesBuilder; +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.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AclWriterTest extends WriterCustomizerTest { + + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = EthAcl.class; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey(ACL_NAME, ACL_TYPE)); + + @Mock + private Acl acl; + private IetfAclWriter customizer; + + @Override + public void setUp() { + customizer = new IetfAclWriter(); + when(acl.getAclName()).thenReturn(ACL_NAME); + doReturn(ACL_TYPE).when(acl).getAclType(); + } + + private void defineInterfacesContext(final List interfaces) { + when(writeContext.readAfter(InstanceIdentifier.create(Interfaces.class))).thenReturn(Optional.of( + new InterfacesBuilder().setInterface(interfaces).build() + )); + } + + @Test + public void testWrite() throws Exception { + customizer.writeCurrentAttributes(IID, acl, writeContext); + } + + @Test + public void testUpdate() throws WriteFailedException { + defineInterfacesContext(Collections.emptyList()); + customizer.updateCurrentAttributes(IID, acl, acl, writeContext); + } + + @Test + public void testDelete() throws WriteFailedException { + defineInterfacesContext(Collections.emptyList()); + customizer.deleteCurrentAttributes(IID, acl, writeContext); + } + + @Test(expected = WriteFailedException.class) + public void testDeleteFailed() throws WriteFailedException { + final Interface iface = new InterfaceBuilder().addAugmentation(VppInterfaceAugmentation.class, + new VppInterfaceAugmentationBuilder().setIetfAcl( + new IetfAclBuilder().setIngress( + new IngressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder().setName(ACL_NAME).setType(ACL_TYPE).build()) + ).build() + ).build() + ).build() + ).build() + ).build(); + defineInterfacesContext(Collections.singletonList(iface)); + customizer.deleteCurrentAttributes(IID, acl, writeContext); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriterTest.java new file mode 100644 index 000000000..ec1321670 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceEthWriterTest.java @@ -0,0 +1,94 @@ +/* + * 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.acl.common; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEthBuilder; +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.vpp.acl.rev161214.InterfaceMode; + +public class AceEthWriterTest { + + private AceEthWriter writer; + private PacketHandling action; + private AceEth aceEth; + + @Before + public void setUp() { + initMocks(this); + writer = new AceEthWriter(); + action = new DenyBuilder().setDeny(true).build(); + aceEth = new AceEthBuilder() + .setDestinationMacAddress(new MacAddress("11:22:33:44:55:66")) + .setDestinationMacAddressMask(new MacAddress("ff:ff:ff:ff:ff:ff")) + .setSourceMacAddress(new MacAddress("aa:bb:cc:dd:ee:ff")) + .setSourceMacAddressMask(new MacAddress("ff:ff:ff:00:00:00")) + .build(); + } + + @Test + public void testCreateTable() { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = writer.createTable(aceEth, InterfaceMode.L2, nextTableIndex, 0); + + assertEquals(1, request.isAdd); + assertEquals(-1, request.tableIndex); + assertEquals(1, request.nbuckets); + assertEquals(nextTableIndex, request.nextTableIndex); + assertEquals(0, request.skipNVectors); + assertEquals(AceEthWriter.MATCH_N_VECTORS, request.matchNVectors); + assertEquals(AceEthWriter.TABLE_MEM_SIZE, request.memorySize); + + byte[] expectedMask = new byte[] { + // destination MAC: + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + // source MAC: + (byte) 0xff, (byte) 0xff, (byte) 0xff, 0, 0, 0, + 0, 0, 0, 0 + }; + assertArrayEquals(expectedMask, request.mask); + } + + @Test + public void testCreateClassifySession() { + final int tableIndex = 123; + final ClassifyAddDelSession request = writer.createSession(action, aceEth, InterfaceMode.L2, tableIndex, 0).get(0); + + assertEquals(1, request.isAdd); + assertEquals(tableIndex, request.tableIndex); + assertEquals(0, request.hitNextIndex); + + byte[] expectedMatch = new byte[] { + // destination MAC: + (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, + // source MAC: + (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, + 0, 0, 0, 0 + }; + assertArrayEquals(expectedMatch, request.match); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4WriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4WriterTest.java new file mode 100644 index 000000000..cb3b246c6 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp4WriterTest.java @@ -0,0 +1,189 @@ +/* + * 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.acl.common; + +import static io.fd.hc2vpp.v3po.interfaces.acl.common.AclTranslator.VLAN_TAG_LEN; +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; + +public class AceIp4WriterTest { + + private AceIp4Writer writer; + private PacketHandling action; + private AceIp aceIp; + + @Before + public void setUp() throws Exception { + initMocks(this); + writer = new AceIp4Writer(); + action = new DenyBuilder().setDeny(true).build(); + aceIp = new AceIpBuilder() + .setProtocol((short) 132) + .setDscp(new Dscp((short) 11)) + .setAceIpVersion(new AceIpv4Builder() + .setSourceIpv4Network(new Ipv4Prefix("1.2.3.4/32")) + .setDestinationIpv4Network(new Ipv4Prefix("1.2.4.5/24")) + .build()) + .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) + .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) + .build(); + } + + private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex, + final int vlanTags, final boolean isL2) { + assertEquals(1, request.isAdd); + assertEquals(-1, request.tableIndex); + assertEquals(1, request.nbuckets); + assertEquals(nextTableIndex, request.nextTableIndex); + assertEquals(0, request.skipNVectors); + assertEquals(AceIp4Writer.MATCH_N_VECTORS, request.matchNVectors); + assertEquals(AceIp4Writer.TABLE_MEM_SIZE, request.memorySize); + + byte[] expectedMask = new byte[] { + // L2: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // dscp: + (byte) 0x00, (byte) 0xfc, + // protocol: + 0, 0, 0, 0, 0, 0, 0, (byte) 0xff, 0, 0, + // source address: + -1, -1, -1, -1, + // destination address: + -1, -1, -1, 0, + // source and destination port: + -1, -1, -1, -1, + // padding: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (isL2) { + expectedMask[12] = (byte) 0xff; + expectedMask[13] = (byte) 0xff; + } + AceIpWriterTestUtils + .assertArrayEqualsWithOffset(expectedMask, expectedMask.length, request.mask, vlanTags * VLAN_TAG_LEN); + + } + + private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex, + final int vlanTags, final boolean isL2) { + assertEquals(1, request.isAdd); + assertEquals(tableIndex, request.tableIndex); + assertEquals(0, request.hitNextIndex); + + byte[] expectedMatch = new byte[] { + // L2: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // dscp: + 0, (byte) 0x2c, + // protocol (132): + 0, 0, 0, 0, 0, 0, 0, (byte) 132, 0, 0, + // source address: + 1, 2, 3, 4, + // destination address: + 1, 2, 4, 0, + // source and destination port: + 0x11, 0x11, 0x22, 0x22, + // padding: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (isL2) { + expectedMatch[12] = (byte) 0x08; + expectedMatch[13] = (byte) 0x00; + } + AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMatch, expectedMatch.length, request.match, vlanTags * VLAN_TAG_LEN); + + } + + @Test + public void testCreateTable() throws Exception { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, 0); + verifyTableRequest(request, nextTableIndex, 0, false); + } + + @Test + public void testCreateTableForL2Interface() throws Exception { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L2, nextTableIndex, 0); + verifyTableRequest(request, nextTableIndex, 0, true); + } + + @Test + public void testCreateTable1VlanTag() throws Exception { + final int nextTableIndex = 42; + final int vlanTags = 1; + final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); + verifyTableRequest(request, nextTableIndex, vlanTags, false); + } + + @Test + public void testCreateTable2VlanTags() throws Exception { + final int nextTableIndex = 42; + final int vlanTags = 2; + final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); + verifyTableRequest(request, nextTableIndex, vlanTags, false); + } + + @Test + public void testCreateClassifySession() throws Exception { + final int tableIndex = 123; + final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, 0).get(0); + verifySessionRequest(request, tableIndex, 0, false); + } + + @Test + public void testCreateClassifySessionForL2Interface() throws Exception { + final int tableIndex = 123; + final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L2, tableIndex, 0).get(0); + verifySessionRequest(request, tableIndex, 0, true); + } + + @Test + public void testCreateClassifySession1VlanTag() throws Exception { + final int tableIndex = 123; + final int vlanTags = 1; + final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); + verifySessionRequest(request, tableIndex, vlanTags, false); + } + + @Test + public void testCreateClassifySession2VlanTags() throws Exception { + final int tableIndex = 123; + final int vlanTags = 2; + final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); + + verifySessionRequest(request, tableIndex, vlanTags, false); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6WriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6WriterTest.java new file mode 100644 index 000000000..30dff951b --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIp6WriterTest.java @@ -0,0 +1,200 @@ +/* + * 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.acl.common; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6FlowLabel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; + +public class AceIp6WriterTest { + + private AceIp6Writer writer; + private PacketHandling action; + private AceIp aceIp; + + @Before + public void setUp() { + initMocks(this); + writer = new AceIp6Writer(); + action = new DenyBuilder().setDeny(true).build(); + aceIp = new AceIpBuilder() + .setProtocol((short) 132) + .setDscp(new Dscp((short) 11)) + .setAceIpVersion(new AceIpv6Builder() + .setFlowLabel(new Ipv6FlowLabel(123L)) + .setSourceIpv6Network(new Ipv6Prefix("2001:db8:85a3:8d3:1319:8a2e:370:7348/128")) + .setDestinationIpv6Network(new Ipv6Prefix("fe80:1234:5678:abcd:ef01::/64")) + .build()) + .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) + .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) + .build(); + } + + + private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex, + final int vlanTags, final boolean isL2) { + assertEquals(1, request.isAdd); + assertEquals(-1, request.tableIndex); + assertEquals(1, request.nbuckets); + assertEquals(nextTableIndex, request.nextTableIndex); + assertEquals(0, request.skipNVectors); + assertEquals(vlanTags == 2 ? 5 : 4, request.matchNVectors); + assertEquals(AceIp6Writer.TABLE_MEM_SIZE, request.memorySize); + + byte[] expectedMask = new byte[] { + // L2: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // dscp, flow: + (byte) 0x0f, (byte) 0xcf, (byte) 0xff, (byte) 0xff, + // protocol: + 0, 0, (byte) 0xff, 0, + // source address: + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + // destination address: + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + 0, 0, 0, 0, 0, 0, 0, 0, + // source and destination port: + -1, -1, -1, -1, + // padding to multiple of 16B: + 0, 0, 0, 0, 0, 0 + }; + + if (isL2) { + expectedMask[12] = (byte) 0xff; + expectedMask[13] = (byte) 0xff; + } + AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMask, vlanTags == 2 ? 80 : 64, request.mask, vlanTags * AclTranslator.VLAN_TAG_LEN); + } + + private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex, + final int vlanTags, final boolean isL2) { + assertEquals(1, request.isAdd); + assertEquals(tableIndex, request.tableIndex); + assertEquals(0, request.hitNextIndex); + + byte[] expectedMatch = new byte[] { + // L2: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // dscp(11), flow(123): + (byte) 0x02, (byte) 0xc0, (byte) 0x00, (byte) 0x7b, + // protocol (132): + 0, 0, (byte) 132, 0, + // source address: + (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, (byte) 0x85, (byte) 0xa3, (byte) 0x08, (byte) 0xd3, + (byte) 0x13, (byte) 0x19, (byte) 0x8a, (byte) 0x2e, (byte) 0x03, (byte) 0x70, (byte) 0x73, (byte) 0x48, + // destination address: + (byte) 0xfe, (byte) 0x80, (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0xab, (byte) 0xcd, + 0, 0, 0, 0, 0, 0, 0, 0, + // source and destination port: + 0x11, 0x11, 0x22, 0x22, + // padding to multiple of 16B: + 0, 0, 0, 0, 0, 0 + }; + + if (isL2) { + expectedMatch[12] = (byte) 0x86; + expectedMatch[13] = (byte) 0xdd; + } + AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMatch, vlanTags == 2 ? 80 : 64, request.match, vlanTags * AclTranslator.VLAN_TAG_LEN); + + } + + @Test + public void testCreateTable() { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = + writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, 0); + verifyTableRequest(request, nextTableIndex, 0, false); + } + + @Test + public void testCreateTableForL2Interface() { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = + writer.createTable(aceIp, InterfaceMode.L2, nextTableIndex, 0); + verifyTableRequest(request, nextTableIndex, 0, true); + } + + @Test + public void testCreateTable1VlanTag() { + final int nextTableIndex = 42; + final int vlanTags = 1; + final ClassifyAddDelTable request = + writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); + verifyTableRequest(request, nextTableIndex, vlanTags, false); + } + + @Test + public void testCreateTable2VlanTags() { + final int nextTableIndex = 42; + final int vlanTags = 2; + final ClassifyAddDelTable request = + writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); + verifyTableRequest(request, nextTableIndex, vlanTags, false); + } + + @Test + public void testCreateClassifySession() { + final int tableIndex = 123; + final ClassifyAddDelSession request = + writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, 0).get(0); + verifySessionRequest(request, tableIndex, 0, false); + } + + @Test + public void testCreateClassifySessionForL2Interface() { + final int tableIndex = 123; + final ClassifyAddDelSession request = + writer.createSession(action, aceIp, InterfaceMode.L2, tableIndex, 0).get(0); + verifySessionRequest(request, tableIndex, 0, true); + } + + @Test + public void testCreateClassifySession1VlanTag() { + final int tableIndex = 123; + final int vlanTags = 1; + final ClassifyAddDelSession request = + writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); + verifySessionRequest(request, tableIndex, vlanTags, false); + } + + @Test + public void testCreateClassifySession2VlanTags() { + final int tableIndex = 123; + final int vlanTags = 2; + final ClassifyAddDelSession request = + writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); + verifySessionRequest(request, tableIndex, vlanTags, false); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java new file mode 100644 index 000000000..34c7334b8 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java @@ -0,0 +1,123 @@ +/* + * 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.acl.common; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder; +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.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEthBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv4Builder; + +public class AceIpAndEthWriterTest { + + private AceIpAndEthWriter writer; + private PacketHandling action; + private AceIpAndEth ace; + + @Before + public void setUp() { + initMocks(this); + writer = new AceIpAndEthWriter(); + action = new DenyBuilder().setDeny(true).build(); + ace = new AceIpAndEthBuilder() + .setDestinationMacAddress(new MacAddress("11:22:33:44:55:66")) + .setSourceMacAddress(new MacAddress("aa:bb:cc:dd:ee:ff")) + .setAceIpVersion(new AceIpv4Builder() + .setSourceIpv4Network(new Ipv4Prefix("1.2.3.4/32")).build()) + .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) + .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) + .build(); + } + + @Test + public void testCreateTable() { + final int nextTableIndex = 42; + final ClassifyAddDelTable request = writer.createTable(ace, InterfaceMode.L2, nextTableIndex, 0); + + assertEquals(1, request.isAdd); + assertEquals(-1, request.tableIndex); + assertEquals(1, request.nbuckets); + assertEquals(nextTableIndex, request.nextTableIndex); + assertEquals(0, request.skipNVectors); + assertEquals(3, request.matchNVectors); + assertEquals(AceEthWriter.TABLE_MEM_SIZE, request.memorySize); + + byte[] expectedMask = new byte[] { + // destination MAC: + -1, -1, -1, -1, -1, -1, + // source MAC: + -1, -1, -1, -1, -1, -1, + // ether type: + -1, -1, + // IP header + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // source address: + -1, -1, -1, -1, + // destination address: + 0, 0, 0, 0, + // source and destination port: + -1, -1, -1, -1, + // padding: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assertArrayEquals(expectedMask, request.mask); + } + + @Test + public void testCreateClassifySession() { + final int tableIndex = 123; + final ClassifyAddDelSession request = writer.createSession(action, ace, InterfaceMode.L2, tableIndex, 0).get(0); + + assertEquals(1, request.isAdd); + assertEquals(tableIndex, request.tableIndex); + assertEquals(0, request.hitNextIndex); + + byte[] expectedMatch = new byte[] { + // destination MAC: + (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, + // source MAC: + (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, + // ether type (IP4): + 0x08, 0, + // IP header + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // source address: + 1, 2, 3, 4, + // destination address: + 0, 0, 0, 0, + // source and destination port: + 0x11, 0x11, 0x22, 0x22, + // padding: + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assertArrayEquals(expectedMatch, request.match); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpWriterTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpWriterTestUtils.java new file mode 100644 index 000000000..087d91d26 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AceIpWriterTestUtils.java @@ -0,0 +1,34 @@ +/* + * 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.acl.common; + +import static org.junit.Assert.assertArrayEquals; + +final class AceIpWriterTestUtils { + + private AceIpWriterTestUtils() { + throw new UnsupportedOperationException("This utility class cannot be instantiated"); + } + + protected static void assertArrayEqualsWithOffset(final byte[] baseExpected, final int expectedLength, final byte[] actual, + final int offset) { + byte[] expected = new byte[expectedLength]; + System.arraycopy(baseExpected, 0, expected, offset, Math.min(baseExpected.length, expectedLength-offset)); + + assertArrayEquals(expected, actual); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java new file mode 100644 index 000000000..3f106ccce --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java @@ -0,0 +1,62 @@ +/* + * 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.acl.common; + +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.honeycomb.translate.MappingContext; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; + +public class AclTableContextManagerImplTest { + + private AclTableContextManagerImpl ctx; + @Mock + private MappingContext mappingContext; + private static final int INDEX = 42; + + @Before + public void setUp() throws Exception { + initMocks(this); + ctx = new AclTableContextManagerImpl(MappingTable.Direction.Ingress); + } + + @Test + public void testAddEntry() throws Exception { + final MappingEntry entry = + new MappingEntryBuilder().setL2TableId(1).setIp4TableId(2).setIp6TableId(3).setIndex(INDEX).build(); + ctx.addEntry(entry, mappingContext); + verify(mappingContext).put(ctx.getId(INDEX), entry); + } + + @Test + public void testRemoveEntry() throws Exception { + ctx.removeEntry(INDEX, mappingContext); + verify(mappingContext).delete(ctx.getId(INDEX)); + } + + @Test + public void testReadEntry() throws Exception { + ctx.getEntry(INDEX, mappingContext); + verify(mappingContext).read(ctx.getId(INDEX)); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPairTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPairTest.java new file mode 100644 index 000000000..f5c319fb6 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/common/PortPairTest.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.interfaces.acl.common; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasSize; + +import java.util.List; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder; + +public class PortPairTest { + + @Test + public void testSingleSrc() { + final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(123)).build(); + final List portPairs = PortPair.fromRange(src, null); + assertThat(portPairs, hasSize(1)); + assertThat(portPairs, contains(new PortPair(123, null))); + } + + @Test + public void testSrcRange() { + final SourcePortRange src = new SourcePortRangeBuilder() + .setLowerPort(new PortNumber(123)) + .setUpperPort(new PortNumber(125)).build(); + final List portPairs = PortPair.fromRange(src, null); + assertThat(portPairs, hasSize(3)); + assertThat(portPairs, contains(new PortPair(123, null), new PortPair(124, null), new PortPair(125, null))); + } + + @Test + public void testSrcRangeWithDst() { + final SourcePortRange src = new SourcePortRangeBuilder() + .setLowerPort(new PortNumber(123)) + .setUpperPort(new PortNumber(125)).build(); + final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(111)).build(); + final List portPairs = PortPair.fromRange(src, dst); + assertThat(portPairs, hasSize(3)); + assertThat(portPairs, contains(new PortPair(123, 111), new PortPair(124, 111), new PortPair(125, 111))); + } + + @Test + public void testSingleDst() { + final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(123)).build(); + final List portPairs = PortPair.fromRange(null, dst); + assertThat(portPairs, hasSize(1)); + assertThat(portPairs, contains(new PortPair(null, 123))); + } + + @Test + public void testDstRange() { + final DestinationPortRange dst = new DestinationPortRangeBuilder() + .setLowerPort(new PortNumber(10)) + .setUpperPort(new PortNumber(11)).build(); + final List portPairs = PortPair.fromRange(null, dst); + assertThat(portPairs, hasSize(2)); + assertThat(portPairs, contains(new PortPair(null, 10), new PortPair(null, 11))); + } + + @Test + public void testDstRangeWithSrc() { + final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(111)).build(); + final DestinationPortRange dst = new DestinationPortRangeBuilder() + .setLowerPort(new PortNumber(10)) + .setUpperPort(new PortNumber(11)).build(); + final List portPairs = PortPair.fromRange(src, dst); + assertThat(portPairs, hasSize(2)); + assertThat(portPairs, contains(new PortPair(111, 10), new PortPair(111, 11))); + } + + @Test + public void testSinglePair() { + final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(123)).build(); + final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(321)).build(); + final List portPairs = PortPair.fromRange(src, dst); + assertThat(portPairs, hasSize(1)); + assertThat(portPairs, contains(new PortPair(123, 321))); + } + + @Test + public void testCartesianProduct() { + final SourcePortRange src = new SourcePortRangeBuilder() + .setLowerPort(new PortNumber(1)) + .setUpperPort(new PortNumber(2)).build(); + final DestinationPortRange dst = new DestinationPortRangeBuilder() + .setLowerPort(new PortNumber(1)) + .setUpperPort(new PortNumber(3)).build(); + final List portPairs = PortPair.fromRange(src, dst); + assertThat(portPairs, hasSize(6)); + assertThat(portPairs, + contains(new PortPair(1, 1), new PortPair(1, 2), new PortPair(1, 3), new PortPair(2, 1), new PortPair(2, 2), + new PortPair(2, 3))); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java new file mode 100644 index 000000000..0b75b5bce --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java @@ -0,0 +1,151 @@ +/* + * 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.acl.egress; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2Tables; +import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2TablesReply; +import java.util.Collections; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.AceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.ActionsBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.MatchesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.PermitBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.EgressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class EgressIetfAclWriterTest extends WriterCustomizerTest { + + private static final int IF_INDEX = 1; + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = EthAcl.class; + + private EgressIetfAclWriter writer; + @Mock + private AclTableContextManager aclCtx; + @Mock + private InstanceIdentifier id; + + @Override + protected void setUp() throws Exception { + writer = new EgressIetfAclWriter(api, aclCtx); + } + + private static ClassifyAddDelTable classifyAddDelTable(final int tableIndex) { + final ClassifyAddDelTable reply = new ClassifyAddDelTable(); + reply.tableIndex = tableIndex; + return reply; + } + + private ClassifySetInterfaceL2Tables classifySetInterfaceL2TablesRequest() { + final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); + request.isInput = 0; + request.ip4TableIndex = -1; + request.ip6TableIndex = -1; + request.otherTableIndex = -1; + request.swIfIndex = IF_INDEX; + return request; + } + + @Test + public void testDeleteAcl() throws Exception { + when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); + when(api.classifySetInterfaceL2Tables(any())).thenReturn(future(new ClassifySetInterfaceL2TablesReply())); + when(aclCtx.getEntry(IF_INDEX, mappingContext)).thenReturn(Optional.of( + new MappingEntryBuilder() + .setIndex(IF_INDEX) + .setL2TableId(1) + .setIp4TableId(2) + .setIp6TableId(3) + .build())); + + writer.deleteAcl(id, IF_INDEX, mappingContext); + + verify(api).classifySetInterfaceL2Tables(classifySetInterfaceL2TablesRequest()); + verify(api).classifyAddDelTable(classifyAddDelTable(1)); + verify(api).classifyAddDelTable(classifyAddDelTable(2)); + verify(api).classifyAddDelTable(classifyAddDelTable(3)); + verify(aclCtx).removeEntry(IF_INDEX, mappingContext); + } + + @Test + public void testWrite() throws Exception { + when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); + when(api.classifyAddDelSession(any())).thenReturn(future(new ClassifyAddDelSessionReply())); + when(api.classifySetInterfaceL2Tables(any())).thenReturn(future(new ClassifySetInterfaceL2TablesReply())); + + final Egress + acl = new EgressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).setMode(InterfaceMode.L2).build() + ).build(); + + final AccessLists accessLists = acl.getAccessLists(); + + when(writeContext.readAfter(any())).thenReturn(Optional.of( + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() + .setAccessListEntries( + new AccessListEntriesBuilder().setAce(Collections.singletonList(new AceBuilder() + .setMatches(new MatchesBuilder().setAceType( + new AceIpBuilder() + .setAceIpVersion(new AceIpv4Builder().build()) + .setProtocol((short) 1) + .build() + ).build()) + .setActions(new ActionsBuilder().setPacketHandling(new PermitBuilder().build()).build()) + .build())).build() + ).build() + + )); + + writer.write(id, IF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, mappingContext); + + final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); + request.isInput = 0; + request.swIfIndex = IF_INDEX; + request.otherTableIndex = -1; + request.ip4TableIndex = 0; + request.ip6TableIndex = -1; + verify(api).classifySetInterfaceL2Tables(request); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java new file mode 100644 index 000000000..07e6518e5 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/IetfAclCustomizerTest.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.interfaces.acl.egress; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import io.fd.hc2vpp.v3po.interfaces.acl.common.IetfAclWriter; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import java.util.Collections; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +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.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.EgressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.MixedAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class IetfAclCustomizerTest extends WriterCustomizerTest { + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + VppInterfaceAugmentation.class).child(IetfAcl.class).child(Egress.class); + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = MixedAcl.class; + + @Mock + private IetfAclWriter aclWriter; + private IetfAclCustomizer customizer; + + @Override + protected void setUp() { + customizer = new IetfAclCustomizer(aclWriter, new NamingContext("prefix", IFC_TEST_INSTANCE)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + } + + private static Egress acl(final InterfaceMode mode) { + return new EgressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).setMode(mode) + .build() + ).build(); + } + + private void verifyWrite(final AccessLists accessLists) throws WriteFailedException { + verify(aclWriter) + .write(IID, IF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, mappingContext); + } + + private void verifyDelete() throws WriteFailedException { + verify(aclWriter).deleteAcl(IID, IF_INDEX, mappingContext); + } + + @Test + public void testWriteL3() throws Exception { + customizer.writeCurrentAttributes(IID, acl(InterfaceMode.L3), writeContext); + verifyZeroInteractions(aclWriter); + } + + @Test + public void testWriteL2() throws Exception { + final Egress acl = acl(InterfaceMode.L2); + customizer.writeCurrentAttributes(IID, acl, writeContext); + verifyWrite(acl.getAccessLists()); + } + + @Test + public void testUpdate() throws Exception { + final Egress aclBefore = acl(InterfaceMode.L3); + final Egress aclAfter = acl(InterfaceMode.L2); + customizer.updateCurrentAttributes(IID, aclBefore, aclAfter, writeContext); + verifyDelete(); + verifyWrite(aclAfter.getAccessLists()); + } + + @Test + public void testDelete() throws Exception { + final Egress acl = acl(InterfaceMode.L2); + customizer.deleteCurrentAttributes(IID, acl, writeContext); + verifyDelete(); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java new file mode 100644 index 000000000..24c57a1d5 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.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.hc2vpp.v3po.interfaces.acl.egress; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.v3po.interfaces.acl.common.IetfAclWriter; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import java.util.Collections; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +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.vpp.acl.rev161214.InterfaceMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.MixedAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.EgressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceIetfAclCustomizerTest extends WriterCustomizerTest { + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUBIF_NAME = "local0.0"; + private static final int SUBIF_INDEX = 11; + private static final long SUBIF_ID = 0; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(IetfAcl.class).child(Egress.class); + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = MixedAcl.class; + + @Mock + private IetfAclWriter aclWriter; + private SubInterfaceIetfAclCustomizer customizer; + + @Override + protected void setUp() { + customizer = new SubInterfaceIetfAclCustomizer(aclWriter, new NamingContext("prefix", IFC_TEST_INSTANCE)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); + + + when(writeContext.readAfter(IID.firstIdentifierOf(SubInterface.class))).thenReturn(Optional.of( + new SubInterfaceBuilder().build() + )); + } + + private static Egress acl(final InterfaceMode mode) { + return new EgressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).setMode(mode) + .build() + ).build(); + } + + private void verifyWrite(final AccessLists accessLists) throws WriteFailedException { + verify(aclWriter) + .write(IID, SUBIF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), + writeContext, 0, mappingContext); + } + + private void verifyDelete() throws WriteFailedException { + verify(aclWriter).deleteAcl(IID, SUBIF_INDEX, mappingContext); + } + + @Test + public void testWriteL3() throws Exception { + customizer.writeCurrentAttributes(IID, acl(InterfaceMode.L3), writeContext); + verifyZeroInteractions(aclWriter); + } + + @Test + public void testWriteL2() throws Exception { + final Egress acl = acl(InterfaceMode.L2); + customizer.writeCurrentAttributes(IID, acl, writeContext); + verifyWrite(acl.getAccessLists()); + } + + @Test + public void testUpdate() throws Exception { + final Egress aclBefore = acl(InterfaceMode.L3); + final Egress aclAfter = acl(InterfaceMode.L2); + customizer.updateCurrentAttributes(IID, aclBefore, aclAfter, writeContext); + verifyDelete(); + verifyWrite(aclAfter.getAccessLists()); + } + + @Test + public void testDelete() throws Exception { + final Egress acl = acl(InterfaceMode.L2); + customizer.deleteCurrentAttributes(IID, acl, writeContext); + verifyDelete(); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java new file mode 100644 index 000000000..9b7267d52 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java @@ -0,0 +1,205 @@ +/* + * 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.acl.ingress; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import java.util.Arrays; +import java.util.Collections; +import org.junit.Test; +import org.mockito.ArgumentMatcher; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.AceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.ActionsBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.MatchesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Deny; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.PermitBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6Builder; +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.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.IngressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class IetfAclCustomizerTest extends WriterCustomizerTest { + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + VppInterfaceAugmentation.class).child(IetfAcl.class).child(Ingress.class); + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = EthAcl.class; + + @Mock + private AclTableContextManager aclCtx; + + private IetfAclCustomizer customizer; + private Ingress acl; + private int DENY = 0; + private int PERMIT = -1; + + @Override + protected void setUp() { + customizer = new IetfAclCustomizer(new IngressIetfAclWriter(api, aclCtx), new NamingContext("prefix", IFC_TEST_INSTANCE)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + acl = new IngressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).build() + ).build(); + } + + @Test + public void testWrite() throws WriteFailedException { + when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); + when(api.classifyAddDelSession(any())).thenReturn(future(new ClassifyAddDelSessionReply())); + + when(writeContext.readAfter(any())).thenReturn(Optional.of( + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() + .setAccessListEntries( + new AccessListEntriesBuilder().setAce(Arrays.asList(ace(permit()), ace(permit()), ace(deny()) + )).build() + ).build() + + )); + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + + customizer.writeCurrentAttributes(IID, acl, writeContext); + + final InOrder inOrder = Mockito.inOrder(api); + inOrder.verify(api).classifyAddDelTable(argThat(actionOnMissEquals(DENY))); // default action + inOrder.verify(api).classifyAddDelTable(any()); + inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(DENY))); // last deny ACE + inOrder.verify(api).classifyAddDelTable(any()); + inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(PERMIT))); + inOrder.verify(api).classifyAddDelTable(any()); + inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(PERMIT))); + inOrder.verify(api).inputAclSetInterface(inputAclSetInterfaceWriteRequest()); // assignment + } + + private ArgumentMatcher actionOnMissEquals(final int action) { + return table -> table.missNextIndex == action; + } + + + private ArgumentMatcher actionOnHitEquals(final int action) { + return session -> session.hitNextIndex == action; + } + + private Deny deny() { + return new DenyBuilder().build(); + } + + private Permit permit() { + return new PermitBuilder().build(); + } + + private static Ace ace(final PacketHandling action) { + return new AceBuilder() + .setMatches(new MatchesBuilder().setAceType( + new AceIpBuilder() + .setAceIpVersion(new AceIpv6Builder().build()) + .setProtocol((short) 1) + .build() + ).build()) + .setActions(new ActionsBuilder().setPacketHandling(action).build()) + .build(); + } + + @Test + public void testDelete() throws WriteFailedException { + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); + when(aclCtx.getEntry(IF_INDEX, mappingContext)).thenReturn(Optional.of( + new MappingEntryBuilder() + .setIndex(IF_INDEX) + .setL2TableId(1) + .setIp4TableId(2) + .setIp6TableId(3) + .build())); + + customizer.deleteCurrentAttributes(IID, acl, writeContext); + + final ClassifyTableByInterface expectedRequest = new ClassifyTableByInterface(); + expectedRequest.swIfIndex = IF_INDEX; + verify(api).inputAclSetInterface(inputAclSetInterfaceDeleteRequest()); + verify(api).classifyAddDelTable(classifyAddDelTable(1)); + verify(api).classifyAddDelTable(classifyAddDelTable(2)); + verify(api).classifyAddDelTable(classifyAddDelTable(3)); + } + + private static InputAclSetInterface inputAclSetInterfaceDeleteRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.swIfIndex = IF_INDEX; + request.l2TableIndex = 1; + request.ip4TableIndex = 2; + request.ip6TableIndex = 3; + return request; + } + + private static ClassifyAddDelTable classifyAddDelTable(final int tableIndex) { + final ClassifyAddDelTable reply = new ClassifyAddDelTable(); + reply.tableIndex = tableIndex; + return reply; + } + + private static InputAclSetInterface inputAclSetInterfaceWriteRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.swIfIndex = IF_INDEX; + request.isAdd = 1; + request.l2TableIndex = -1; + request.ip4TableIndex = -1; + request.ip6TableIndex = 0; + return request; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java new file mode 100644 index 000000000..8b088883f --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java @@ -0,0 +1,140 @@ +/* + * 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.acl.ingress; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import org.junit.Test; +import org.mockito.Mock; +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.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceAclCustomizerTest extends WriterCustomizerTest { + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUBIF_NAME = "local0.0"; + private static final int SUBIF_INDEX = 11; + private static final long SUBIF_ID = 0; + private static final String TABLE_NAME = "table0"; + private static final int TABLE_INDEX = 123; + + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(Acl.class).child(Ingress.class); + + @Mock + private VppClassifierContextManager classifyTableContext; + + private SubInterfaceAclCustomizer customizer; + + @Override + protected void setUp() throws Exception { + customizer = new SubInterfaceAclCustomizer(api, new NamingContext("prefix", IFC_TEST_INSTANCE), + classifyTableContext); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); + when(classifyTableContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + } + + @Test + public void testCreate() throws WriteFailedException { + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext); + verify(api).inputAclSetInterface(expectedIp4AclRequest()); + } + + @Test(expected = WriteFailedException.class) + public void testCreateFailed() throws WriteFailedException { + when(api.inputAclSetInterface(any())).thenReturn(failedFuture()); + customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdate() throws WriteFailedException { + customizer.updateCurrentAttributes(IID, ip4Acl(), ip6Acl(), writeContext); + } + + @Test + public void testDelete() throws Exception { + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + customizer.deleteCurrentAttributes(IID, ip6Acl(), writeContext); + verify(api).inputAclSetInterface(expectedIp6AclRequest()); + } + + @Test(expected = WriteFailedException.class) + public void testDeleteFailed() throws WriteFailedException { + when(api.inputAclSetInterface(any())).thenReturn(failedFuture()); + customizer.deleteCurrentAttributes(IID, ip4Acl(), writeContext); + } + + private Ingress ip4Acl() { + final IngressBuilder builder = new IngressBuilder(); + final Ip4Acl acl = new Ip4AclBuilder().setClassifyTable(TABLE_NAME).build(); + builder.setIp4Acl(acl); + return builder.build(); + } + + private InputAclSetInterface expectedIp4AclRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = 1; + request.l2TableIndex = -1; + request.ip4TableIndex = TABLE_INDEX; + request.ip6TableIndex = -1; + request.swIfIndex = SUBIF_INDEX; + return request; + } + + private Ingress ip6Acl() { + final IngressBuilder builder = new IngressBuilder(); + final Ip6Acl acl = new Ip6AclBuilder().setClassifyTable(TABLE_NAME).build(); + builder.setIp6Acl(acl); + return builder.build(); + } + + private InputAclSetInterface expectedIp6AclRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.isAdd = 0; + request.l2TableIndex = -1; + request.ip4TableIndex = -1; + request.ip6TableIndex = TABLE_INDEX; + request.swIfIndex = SUBIF_INDEX; + return request; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java new file mode 100644 index 000000000..e3c1d86f9 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java @@ -0,0 +1,155 @@ +/* + * 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.acl.ingress; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.v3po.interfaces.acl.IetfAclWriter; +import io.fd.hc2vpp.v3po.interfaces.acl.common.AclTableContextManager; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; +import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; +import java.util.Collections; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; +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.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.IetfAcl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceIetfAclCustomizerTest extends WriterCustomizerTest { + + private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUBIF_NAME = "local0.123"; + private static final int SUBIF_INDEX = 2; + private static final long SUB_IF_ID = 123; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)).child(IetfAcl.class).child(Ingress.class); + private static final String ACL_NAME = "acl1"; + private static final Class ACL_TYPE = EthAcl.class; + + private SubInterfaceIetfAclCustomizer customizer; + private Ingress acl; + + @Mock + private AclTableContextManager aclCtx; + + @Override + protected void setUp() { + customizer = + new SubInterfaceIetfAclCustomizer(new IngressIetfAclWriter(api, aclCtx), new NamingContext("prefix", IFC_TEST_INSTANCE)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + + acl = new IngressBuilder().setAccessLists( + new AccessListsBuilder().setAcl( + Collections.singletonList(new AclBuilder() + .setName(ACL_NAME) + .setType(ACL_TYPE) + .build()) + ).build() + ).build(); + } + + private static InputAclSetInterface inputAclSetInterfaceWriteRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.swIfIndex = SUBIF_INDEX; + request.isAdd = 1; + request.l2TableIndex = -1; + request.ip4TableIndex = -1; + request.ip6TableIndex = -1; + return request; + } + + @Test + public void testDelete() throws WriteFailedException { + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + when(aclCtx.getEntry(SUBIF_INDEX, mappingContext)).thenReturn(Optional.of( + new MappingEntryBuilder() + .setIndex(SUBIF_INDEX) + .setL2TableId(-1) + .setIp4TableId(-1) + .setIp6TableId(-1) + .build())); + + customizer.deleteCurrentAttributes(IID, acl, writeContext); + + final ClassifyTableByInterface expectedRequest = new ClassifyTableByInterface(); + expectedRequest.swIfIndex = SUBIF_INDEX; + verify(api).inputAclSetInterface(inputAclSetInterfaceDeleteRequest()); + } + + private static InputAclSetInterface inputAclSetInterfaceDeleteRequest() { + final InputAclSetInterface request = new InputAclSetInterface(); + request.swIfIndex = SUBIF_INDEX; + request.l2TableIndex = -1; + request.ip4TableIndex = -1; + request.ip6TableIndex = -1; + return request; + } + + @Test + public void testWrite() throws WriteFailedException { + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); + + when(writeContext.readAfter(IID.firstIdentifierOf(SubInterface.class))).thenReturn(Optional.of( + new SubInterfaceBuilder().build() + )); + + when(writeContext.readAfter(IetfAclWriter.ACL_ID.child( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl.class, + new AclKey(ACL_NAME, ACL_TYPE)))).thenReturn(Optional.of( + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() + .setAccessListEntries( + new AccessListEntriesBuilder().setAce(Collections.emptyList()).build() + ).build() + )); + + when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); + + customizer.writeCurrentAttributes(IID, acl, writeContext); + + verify(api).inputAclSetInterface(inputAclSetInterfaceWriteRequest()); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java new file mode 100644 index 000000000..6659e79b6 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java @@ -0,0 +1,338 @@ +/* + * 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.ip; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.v3po.interfaces.ip.subnet.validation.SubnetValidationException; +import io.fd.hc2vpp.v3po.interfaces.ip.subnet.validation.SubnetValidator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +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.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.NetmaskBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddress; +import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddressReply; + +public class Ipv4AddressCustomizerTest extends WriterCustomizerTest { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IFACE_NAME = "eth0"; + private static final int IFACE_ID = 123; + + @Mock + private SubnetValidator subnetValidator; + + private NamingContext interfaceContext; + private Ipv4AddressCustomizer customizer; + + @Before + public void setUp() throws Exception { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + + customizer = new Ipv4AddressCustomizer(api, interfaceContext, subnetValidator); + + doReturn(future(new IpAddressDetailsReplyDump())).when(api).ipAddressDump(any()); + when(writeContext.readAfter(Mockito.any())) + .thenReturn(Optional.of(new Ipv4Builder().setAddress(Collections.emptyList()).build())); + } + + private static InstanceIdentifier

getAddressId(final String ifaceName) { + return InstanceIdentifier.builder(Interfaces.class) + .child(Interface.class, new InterfaceKey(ifaceName)) + .augmentation(Interface1.class) + .child(Ipv4.class) + .child(Address.class) + .build(); + } + + private void whenSwInterfaceAddDelAddressThenSuccess() { + doReturn(future(new SwInterfaceAddDelAddressReply())).when(api).swInterfaceAddDelAddress(any(SwInterfaceAddDelAddress.class)); + } + + private void whenSwInterfaceAddDelAddressThenFailure() { + doReturn(failedFuture()).when(api).swInterfaceAddDelAddress(any(SwInterfaceAddDelAddress.class)); + } + + @Test + public void testAddPrefixLengthIpv4Address() throws Exception { + doNothing().when(subnetValidator).checkNotAddingToSameSubnet(Mockito.anyList()); + + final InstanceIdentifier
id = getAddressId(IFACE_NAME); + when(writeContext.readBefore(id)).thenReturn(Optional.absent()); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); + Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); + + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + whenSwInterfaceAddDelAddressThenSuccess(); + + customizer.writeCurrentAttributes(id, data, writeContext); + + verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, + (byte) 1, (byte) 24)); + } + + @Test + public void testAddPrefixLengthIpv4AddressFailed() throws Exception { + final InstanceIdentifier
id = getAddressId(IFACE_NAME); + when(writeContext.readBefore(id)).thenReturn(Optional.absent()); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); + Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); + + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + whenSwInterfaceAddDelAddressThenFailure(); + + try { + customizer.writeCurrentAttributes(id, data, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).swInterfaceAddDelAddress( + generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, + (byte) 1, (byte) 24)); + return; + } + fail("WriteFailedException was expected"); + } + + @Test + public void testAddPrefixLengthIpv4AddressConflicted() throws Exception { + + final InstanceIdentifier
id = getAddressId(IFACE_NAME); + when(writeContext.readBefore(id)).thenReturn(Optional.absent()); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); + Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); + final List
addressList = Arrays.asList(data); + + //throws when validation invoked + Mockito.doThrow(SubnetValidationException.forConflictingData((short) 24, Arrays.asList(data))).when(subnetValidator) + .checkNotAddingToSameSubnet(addressList); + + //fake data return from WriteContext + doReturn(Optional.of(new Ipv4Builder().setAddress(addressList).build())).when(writeContext) + .readAfter(argThat(matchInstanceIdentifier(Ipv4.class))); + + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + + try { + customizer.writeCurrentAttributes(id, data, writeContext); + } catch (WriteFailedException e) { + //verifies if cause of exception is correct type + assertTrue(e.getCause() instanceof SubnetValidationException); + + //verify that validation call was invoked with data from writeContext + verify(subnetValidator, times(1)).checkNotAddingToSameSubnet(addressList); + } + + } + + private static ArgumentMatcher> matchInstanceIdentifier( + Class desiredClass) { + return o -> o instanceof InstanceIdentifier && (o.getTargetType().equals(desiredClass)); + } + + @Test(expected = WriteFailedException.UpdateFailedException.class) + public void testUpdate() throws Exception { + final Address data = mock(Address.class); + customizer.updateCurrentAttributes(getAddressId(IFACE_NAME), data, data, writeContext); + } + + private SwInterfaceAddDelAddress generateSwInterfaceAddDelAddressRequest(final byte[] address, final byte isAdd, + final byte prefixLength) { + final SwInterfaceAddDelAddress request = new SwInterfaceAddDelAddress(); + request.swIfIndex = IFACE_ID; + request.isAdd = isAdd; + request.isIpv6 = 0; + request.delAll = 0; + request.addressLength = prefixLength; + request.address = address; + return request; + } + + @Test + public void testDeletePrefixLengthIpv4Address() throws Exception { + final InstanceIdentifier
id = getAddressId(IFACE_NAME); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); + Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); + + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + whenSwInterfaceAddDelAddressThenSuccess(); + + customizer.deleteCurrentAttributes(id, data, writeContext); + + verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, + (byte) 0, (byte) 24)); + } + + @Test + public void testDeletePrefixLengthIpv4AddressFailed() throws Exception { + final InstanceIdentifier
id = getAddressId(IFACE_NAME); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); + Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); + + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + whenSwInterfaceAddDelAddressThenFailure(); + + try { + customizer.deleteCurrentAttributes(id, data, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).swInterfaceAddDelAddress( + generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, + (byte) 0, (byte) 24)); + return; + } + fail("WriteFailedException was expec16ted"); + } + + @Test + public void testNetmaskFailed() { + final int expectedPrefixLength = 1; + final String stringMask = "128.0.0.0"; + final InstanceIdentifier
id = getAddressId(IFACE_NAME); + when(writeContext.readBefore(id)).thenReturn(Optional.absent()); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + Netmask subnet = new NetmaskBuilder().setNetmask(new DottedQuad(stringMask)).build(); + Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build(); + + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + whenSwInterfaceAddDelAddressThenFailure(); + + try { + customizer.writeCurrentAttributes(id, data, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, + (byte) 1, (byte) expectedPrefixLength)); + return; + } + fail("WriteFailedException was expec16ted"); + + } + + private void testSingleNetmask(final int expectedPrefixLength, final String stringMask) throws Exception { + final InstanceIdentifier
id = getAddressId(IFACE_NAME); + when(writeContext.readBefore(id)).thenReturn(Optional.absent()); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + Netmask subnet = new NetmaskBuilder().setNetmask(new DottedQuad(stringMask)).build(); + Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build(); + + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + whenSwInterfaceAddDelAddressThenSuccess(); + + customizer.writeCurrentAttributes(id, data, writeContext); + + verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, + (byte) 1, (byte) expectedPrefixLength)); + } + + private void testSingleIllegalNetmask(final String stringMask) throws Exception { + try { + final InstanceIdentifier
id = getAddressId(IFACE_NAME); + when(writeContext.readBefore(id)).thenReturn(Optional.absent()); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + Netmask subnet = new NetmaskBuilder().setNetmask(new DottedQuad(stringMask)).build(); + Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build(); + + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + whenSwInterfaceAddDelAddressThenSuccess(); + + customizer.writeCurrentAttributes(id, data, writeContext); + } catch (IllegalArgumentException e) { + return; + } + fail("IllegalArgumentException expected"); + + } + + /** + * Test contiguous netmask length from QuadDotted notation + */ + @Test + public void testNetmaskLength() throws Exception { + testSingleNetmask(1, "128.0.0.0"); + testSingleNetmask(2, "192.0.0.0"); + testSingleNetmask(8, "255.0.0.0"); + testSingleNetmask(9, "255.128.0.0"); + testSingleNetmask(16, "255.255.0.0"); + testSingleNetmask(24, "255.255.255.0"); + } + + @Test + public void testNetmaskIllegal() throws Exception { + testSingleIllegalNetmask(""); + testSingleIllegalNetmask("."); + testSingleIllegalNetmask(".255"); + testSingleIllegalNetmask("255"); + testSingleIllegalNetmask("255."); + testSingleIllegalNetmask("255.255"); + testSingleIllegalNetmask("255.255.0"); + testSingleIllegalNetmask("255.255.255."); + testSingleIllegalNetmask("255.255.255.256"); + testSingleIllegalNetmask("0.0.0.0"); + testSingleIllegalNetmask("10.10.10.10"); + testSingleIllegalNetmask("255.1.255.0"); + testSingleIllegalNetmask("255.255.255.255"); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java new file mode 100644 index 000000000..390561d80 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java @@ -0,0 +1,120 @@ +/* + * 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.ip; + +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +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.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.IpNeighborAddDel; +import io.fd.vpp.jvpp.core.dto.IpNeighborAddDelReply; + +public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest implements Ipv4Translator { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IFACE_NAME = "parent"; + private static final int IFACE_ID = 5; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class); + + private Ipv4NeighbourCustomizer customizer; + + @Override + public void setUp() { + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + customizer = new Ipv4NeighbourCustomizer(api, new NamingContext("prefix", IFC_CTX_NAME)); + } + + @Test + public void testWriteCurrentAttributes() throws WriteFailedException { + when(api.ipNeighborAddDel(any())).thenReturn(future(new IpNeighborAddDelReply())); + customizer.writeCurrentAttributes(IID, getData(), writeContext); + verify(api).ipNeighborAddDel(getExpectedRequest(true)); + } + + @Test + public void testWriteCurrentAttributesFailed() { + when(api.ipNeighborAddDel(any())).thenReturn(failedFuture()); + try { + customizer.writeCurrentAttributes(IID, getData(), writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).ipNeighborAddDel(getExpectedRequest(true)); + return; + } + fail("WriteFailedException expected"); + } + @Test(expected = UnsupportedOperationException.class) + public void testUpdateCurrentAttributes() throws WriteFailedException { + customizer.updateCurrentAttributes(IID, getData(), getData(), writeContext); + } + + @Test + public void testDeleteCurrentAttributes() throws WriteFailedException { + when(api.ipNeighborAddDel(any())).thenReturn(future(new IpNeighborAddDelReply())); + customizer.deleteCurrentAttributes(IID, getData(), writeContext); + verify(api).ipNeighborAddDel(getExpectedRequest(false)); + } + + @Test + public void testDeleteCurrentAttributesFailed() { + when(api.ipNeighborAddDel(any())).thenReturn(failedFuture()); + try { + customizer.deleteCurrentAttributes(IID, getData(), writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).ipNeighborAddDel(getExpectedRequest(false)); + return; + } + fail("WriteFailedException expected"); + } + + private Neighbor getData() { + final Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + final PhysAddress mac = new PhysAddress("aa:bb:cc:ee:11:22"); + return new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build(); + } + private IpNeighborAddDel getExpectedRequest(final boolean isAdd) { + final IpNeighborAddDel request = new IpNeighborAddDel(); + request.isIpv6 = 0; + request.isAdd = booleanToByte(isAdd); + request.isStatic = 1; + request.dstAddress = new byte[] {(byte) 192, (byte) 168, 2, 1}; + request.macAddress = new byte[] {(byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xee, 0x11, 0x22}; + request.swIfIndex = IFACE_ID; + return request; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java new file mode 100644 index 000000000..be0869fa9 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java @@ -0,0 +1,144 @@ +/* + * 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.ip; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +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.DottedQuad; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.Subnet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.Netmask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.NetmaskBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddress; +import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddressReply; + +public class SubInterfaceIpv4AddressCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IFACE_NAME = "eth0"; + private static final int IFACE_INDEX = 0; + private static final String SUBIF_NAME = "eth0.1"; + private static final long SUBIF_ID = 1; + private static final int SUBIF_INDEX = 123; + private static final InstanceIdentifier
IID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(Ipv4.class).child(Address.class); + + private SubInterfaceIpv4AddressCustomizer customizer; + + @Override + protected void setUp() { + customizer = new SubInterfaceIpv4AddressCustomizer(api, new NamingContext("prefix", IFC_CTX_NAME)); + defineMapping(mappingContext, IFACE_NAME, IFACE_INDEX, IFC_CTX_NAME); + defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_CTX_NAME); + } + + @Test + public void testWrite() throws WriteFailedException { + when(api.swInterfaceAddDelAddress(any())).thenReturn(future(new SwInterfaceAddDelAddressReply())); + customizer.writeCurrentAttributes(IID, address(prefixLength()), writeContext); + verify(api).swInterfaceAddDelAddress(expectedRequest(true)); + } + + @Test + public void testWriteFailed() { + when(api.swInterfaceAddDelAddress(any())).thenReturn(failedFuture()); + try { + customizer.writeCurrentAttributes(IID, address(prefixLength()), writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).swInterfaceAddDelAddress(expectedRequest(true)); + return; + } + fail("WriteFailedException expected"); + } + + @Test + public void testDelete() throws WriteFailedException { + when(api.swInterfaceAddDelAddress(any())).thenReturn(future(new SwInterfaceAddDelAddressReply())); + customizer.deleteCurrentAttributes(IID, address(netmask()), writeContext); + verify(api).swInterfaceAddDelAddress(expectedRequest(false)); + } + + @Test + public void testDeleteFailed() { + when(api.swInterfaceAddDelAddress(any())).thenReturn(failedFuture()); + try { + customizer.deleteCurrentAttributes(IID, address(netmask()), writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).swInterfaceAddDelAddress(expectedRequest(false)); + return; + } + fail("WriteFailedException expected"); + } + + private SwInterfaceAddDelAddress expectedRequest(boolean isAdd) { + final SwInterfaceAddDelAddress request = new SwInterfaceAddDelAddress(); + request.isAdd = booleanToByte(isAdd); + request.swIfIndex = SUBIF_INDEX; + request.isIpv6 = 0; + request.delAll = 0; + request.addressLength = 24; + request.address = new byte[] {(byte) 192, (byte) 168, 2, 1}; + return request; + } + + @Test(expected = WriteFailedException.UpdateFailedException.class) + public void testUpdate() throws Exception { + final Address address = address(prefixLength()); + customizer.updateCurrentAttributes(IID, address, address, writeContext); + } + + private Address address(final Subnet subnet) { + final Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + return new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build(); + } + + private PrefixLength prefixLength() { + return new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); + } + + private Netmask netmask() { + return new NetmaskBuilder().setNetmask(new DottedQuad("255.255.255.0")).build(); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidatorTest.java new file mode 100644 index 000000000..0c1e878a8 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidatorTest.java @@ -0,0 +1,88 @@ +/* + * 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.ip.subnet.validation; + + +import com.google.common.collect.Lists; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.NetmaskBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; + +public class SubnetValidatorTest { + + private SubnetValidator subnetValidator; + + @Before + public void init() { + subnetValidator = new SubnetValidator(); + } + + @Test(expected = SubnetValidationException.class) + public void testValidateNegativeSameTypes() throws SubnetValidationException { + List
addresses = Lists.newArrayList(); + + addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) + .build()); + addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) + .build()); + + subnetValidator.checkNotAddingToSameSubnet(addresses); + } + + @Test(expected = SubnetValidationException.class) + public void testValidateNegativeMixedTypes() throws SubnetValidationException { + List
addresses = Lists.newArrayList(); + + addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) + .build()); + addresses.add(new AddressBuilder() + .setSubnet(new NetmaskBuilder().setNetmask(new DottedQuad("255.255.255.0")).build()) + .build()); + + subnetValidator.checkNotAddingToSameSubnet(addresses); + } + + @Test + public void testValidatePositiveSameTypes() throws SubnetValidationException { + List
addresses = Lists.newArrayList(); + + addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) + .build()); + addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 25).build()) + .build()); + + subnetValidator.checkNotAddingToSameSubnet(addresses); + } + + @Test + public void testValidatePositiveMixedTypes() throws SubnetValidationException { + List
addresses = Lists.newArrayList(); + + addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) + .build()); + addresses.add(new AddressBuilder() + .setSubnet(new NetmaskBuilder().setNetmask(new DottedQuad("255.255.0.0")).build()) + .build()); + + subnetValidator.checkNotAddingToSameSubnet(addresses); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java new file mode 100644 index 000000000..fa68e61b6 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java @@ -0,0 +1,312 @@ +/* + * 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.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.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.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.rev161214.Operation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces._interface.PbbRewrite; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.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/hc2vpp/v3po/interfacesstate/EthernetCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizerTest.java new file mode 100644 index 000000000..338d63333 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizerTest.java @@ -0,0 +1,90 @@ +/* + * 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; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import io.fd.hc2vpp.common.test.util.InterfaceDumpHelper; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.EthernetStateAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Ethernet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.EthernetBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; + +public class EthernetCustomizerTest extends ReaderCustomizerTest implements + InterfaceDumpHelper { + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(VppInterfaceStateAugmentation.class).child(Ethernet.class); + private NamingContext interfaceContext; + + public EthernetCustomizerTest() { + super(Ethernet.class, VppInterfaceStateAugmentationBuilder.class); + } + + @Override + protected void setUp() throws Exception { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new EthernetCustomizer(api, interfaceContext); + } + + private void testRead(final int linkDuplex, final EthernetStateAttributes.Duplex duplex) throws ReadFailedException { + final EthernetBuilder builder = mock(EthernetBuilder.class); + final short mtu = 123; + whenSwInterfaceDumpThenReturn(api, ifaceDetails(mtu, linkDuplex)); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + verify(builder).setMtu((int)mtu); + verify(builder).setDuplex(duplex); + } + + private SwInterfaceDetails ifaceDetails(final short mtu, final int duplex) { + final SwInterfaceDetails details = new SwInterfaceDetails(); + details.swIfIndex = IF_INDEX; + details.linkMtu = mtu; + details.linkDuplex = (byte)duplex; + return details; + } + + @Test + public void testReadHalfDuplex() throws ReadFailedException { + testRead(1, EthernetStateAttributes.Duplex.Half); + } + + @Test + public void testReadFullDuplex() throws ReadFailedException { + testRead(2, EthernetStateAttributes.Duplex.Full); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizerTest.java new file mode 100644 index 000000000..1aadb5bd1 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizerTest.java @@ -0,0 +1,131 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import com.google.common.collect.Lists; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Gre; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.GreBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.GreTunnelDetails; +import io.fd.vpp.jvpp.core.dto.GreTunnelDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.GreTunnelDump; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; + +public class GreCustomizerTest extends ReaderCustomizerTest { + + private static final String IFACE_NAME = "ifc1"; + private static final int IFACE_ID = 0; + private static final String IFC_CTX_NAME = "ifc-test-instance"; + + private NamingContext interfacesContext; + static final InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceStateAugmentation.class).child(Gre.class); + + public GreCustomizerTest() { + super(Gre.class, VppInterfaceStateAugmentationBuilder.class); + } + + @Override + public void setUp() throws UnknownHostException, VppInvocationException { + interfacesContext = new NamingContext("gre-tunnel", IFC_CTX_NAME); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + + final SwInterfaceDetails v = new SwInterfaceDetails(); + v.interfaceName = "gre-tunnel4".getBytes(); + final Map map = new HashMap<>(); + map.put(0, v); + cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, map); + + final GreTunnelDetailsReplyDump value = new GreTunnelDetailsReplyDump(); + final GreTunnelDetails greTunnelDetails = new GreTunnelDetails(); + greTunnelDetails.isIpv6 = 0; + greTunnelDetails.dstAddress = InetAddress.getByName("1.2.3.4").getAddress(); + greTunnelDetails.srcAddress = InetAddress.getByName("1.2.3.5").getAddress(); + greTunnelDetails.outerFibId = 55; + greTunnelDetails.swIfIndex = 0; + value.greTunnelDetails = Lists.newArrayList(greTunnelDetails); + + doReturn(future(value)).when(api).greTunnelDump(any(GreTunnelDump.class)); + } + + @Test + public void testReadCurrentAttributes() throws Exception { + final GreBuilder builder = getCustomizer().getBuilder(IID); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + + assertEquals(55, builder.getOuterFibId().intValue()); + + assertNull(builder.getSrc().getIpv6Address()); + assertNotNull(builder.getSrc().getIpv4Address()); + assertEquals("1.2.3.5", builder.getSrc().getIpv4Address().getValue()); + + assertNull(builder.getDst().getIpv6Address()); + assertNotNull(builder.getDst().getIpv4Address()); + assertEquals("1.2.3.4", builder.getDst().getIpv4Address().getValue()); + + verify(api).greTunnelDump(any(GreTunnelDump.class)); + } + + @Test(expected = NullPointerException.class) + public void testReadCurrentAttributesVppNameNotCached() throws Exception { + InterfaceCustomizer.getCachedInterfaceDump(cache).remove(0); + + final GreBuilder builder = getCustomizer().getBuilder(IID); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + } + + @Test + public void testReadCurrentAttributesWrongType() throws Exception { + final SwInterfaceDetails v = new SwInterfaceDetails(); + v.interfaceName = "tap-2".getBytes(); + InterfaceCustomizer.getCachedInterfaceDump(cache).put(0, v); + + final GreBuilder builder = getCustomizer().getBuilder(IID); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + + // Should be ignored + verifyZeroInteractions(api); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new GreCustomizer(api, interfacesContext); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizerTest.java new file mode 100644 index 000000000..295805114 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizerTest.java @@ -0,0 +1,200 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import io.fd.hc2vpp.common.test.util.InterfaceDumpHelper; +import java.util.Arrays; +import java.util.List; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; + +public class InterfaceCustomizerTest extends ListReaderCustomizerTest + implements InterfaceDataTranslator, InterfaceDumpHelper { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IFACE0_NAME = "eth0"; + private static final String IFACE1_NAME = "eth1"; + private static final String SUB_IFACE_NAME = "eth1.1"; + private static final int IFACE0_ID = 0; + private static final int IFACE1_ID = 1; + private static final int SUB_IFACE_ID = 2; + + private NamingContext interfacesContext; + @Mock + private DisabledInterfacesManager interfaceDisableContext; + + public InterfaceCustomizerTest() { + super(Interface.class, InterfacesStateBuilder.class); + } + + @Override + public void setUp() { + interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, IFACE0_NAME, IFACE0_ID, IFC_CTX_NAME); + defineMapping(mappingContext, IFACE1_NAME, IFACE1_ID, IFC_CTX_NAME); + defineMapping(mappingContext, SUB_IFACE_NAME, SUB_IFACE_ID, IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new InterfaceCustomizer(api, interfacesContext, interfaceDisableContext); + } + + private void verifySwInterfaceDumpWasInvoked(final int nameFilterValid, final String ifaceName, + final int dumpIfcsInvocationCount) + throws VppInvocationException { + final SwInterfaceDump expected = new SwInterfaceDump(); + expected.nameFilterValid = (byte) nameFilterValid; + expected.nameFilter = ifaceName.getBytes(); + verify(api, times(dumpIfcsInvocationCount)).swInterfaceDump(expected); + } + + private void assertIfacesAreEqual(final Interface iface, final SwInterfaceDetails details) { + assertEquals(iface.getName(), new String(details.interfaceName)); + assertEquals(yangIfIndexToVpp(iface.getIfIndex().intValue()), details.swIfIndex); + assertEquals(iface.getPhysAddress().getValue(), vppPhysAddrToYang(details.l2Address)); + } + + @Test + public void testReadCurrentAttributes() throws Exception { + final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(IFACE0_NAME)); + final InterfaceBuilder builder = getCustomizer().getBuilder(id); + + final SwInterfaceDetails iface = new SwInterfaceDetails(); + iface.interfaceName = IFACE0_NAME.getBytes(); + iface.swIfIndex = 0; + iface.linkSpeed = 1; + iface.l2AddressLength = 6; + iface.l2Address = new byte[iface.l2AddressLength]; + whenSwInterfaceDumpThenReturn(api, iface); + + getCustomizer().readCurrentAttributes(id, builder, ctx); + + verifySwInterfaceDumpWasInvoked(1, IFACE0_NAME, 1); + assertIfacesAreEqual(builder.build(), iface); + } + + @Test + public void testReadCurrentAttributesFailed() throws Exception { + final String ifaceName = IFACE0_NAME; + final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(ifaceName)); + final InterfaceBuilder builder = getCustomizer().getBuilder(id); + + whenSwInterfaceDumpThenReturn(api); + + try { + getCustomizer().readCurrentAttributes(id, builder, ctx); + } catch (IllegalArgumentException e) { + verifySwInterfaceDumpWasInvoked(0, ifaceName, 2); + return; + } + + fail("ReadFailedException was expected"); + } + + @Test + public void testReadSubInterface() throws Exception { + final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(SUB_IFACE_NAME)); + final InterfaceBuilder builder = mock(InterfaceBuilder.class); + + final SwInterfaceDetails iface = new SwInterfaceDetails(); + iface.interfaceName = SUB_IFACE_NAME.getBytes(); + iface.swIfIndex = 2; + iface.supSwIfIndex = 1; + iface.subId = 1; + whenSwInterfaceDumpThenReturn(api, iface); + + getCustomizer().readCurrentAttributes(id, builder, ctx); + + verifySwInterfaceDumpWasInvoked(1, SUB_IFACE_NAME, 1); + verifyZeroInteractions(builder); + } + + @Test + public void testGetAllIds() throws Exception { + final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class); + + final SwInterfaceDetails swIf0 = new SwInterfaceDetails(); + swIf0.swIfIndex = 0; + swIf0.interfaceName = IFACE0_NAME.getBytes(); + final SwInterfaceDetails swIf1 = new SwInterfaceDetails(); + swIf1.swIfIndex = 1; + swIf1.interfaceName = IFACE1_NAME.getBytes(); + final SwInterfaceDetails swSubIf1 = new SwInterfaceDetails(); + swSubIf1.swIfIndex = 2; + swSubIf1.subId = 1; + swSubIf1.supSwIfIndex = 1; + swSubIf1.interfaceName = SUB_IFACE_NAME.getBytes(); + whenSwInterfaceDumpThenReturn(api, swIf0, swIf1, swSubIf1); + + final List expectedIds = Arrays.asList(new InterfaceKey(IFACE0_NAME), new InterfaceKey( + IFACE1_NAME)); + final List actualIds = getCustomizer().getAllIds(id, ctx); + + verifySwInterfaceDumpWasInvoked(0, "", 1); + + // sub-interface should not be on the list + assertEquals(expectedIds, actualIds); + } + + @Test + public void testGetAllIdsWithDisabled() throws Exception { + final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class); + + doReturn(true).when(interfaceDisableContext).isInterfaceDisabled(1, mappingContext); + + final SwInterfaceDetails swIf0 = new SwInterfaceDetails(); + swIf0.swIfIndex = 0; + swIf0.interfaceName = IFACE0_NAME.getBytes(); + final SwInterfaceDetails swIf1 = new SwInterfaceDetails(); + swIf1.swIfIndex = 1; + swIf1.interfaceName = IFACE1_NAME.getBytes(); + whenSwInterfaceDumpThenReturn(api, swIf0, swIf1); + + final List expectedIds = Arrays.asList(new InterfaceKey(IFACE0_NAME)); + final List actualIds = getCustomizer().getAllIds(id, ctx); + + // disabled interface should not be on the list + assertEquals(expectedIds, actualIds); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslatorTest.java new file mode 100644 index 000000000..7c7f64817 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslatorTest.java @@ -0,0 +1,55 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel; + +public class InterfaceDataTranslatorTest implements InterfaceDataTranslator { + + @Test + public void testVppPhysAddrToYang() throws Exception { + assertEquals("01:02:03:04:05:06", vppPhysAddrToYang(new byte[]{1, 2, 3, 4, 5, 6})); + assertEquals("0a:0b:0c:0d:0e:0f", vppPhysAddrToYang(new byte[]{0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0})); + } + + @Test(expected = NullPointerException.class) + public void testVppPhysAddrToYangFailNullArgument() throws Exception { + vppPhysAddrToYang(null); + } + + @Test(expected = IllegalArgumentException.class) + public void testVppPhysAddrToYangInvalidByteArrayLength() throws Exception { + vppPhysAddrToYang(new byte[]{1, 2, 3, 4, 5}); + } + + @Test + public void testGetInterfaceType() { + assertEquals(Tap.class, getInterfaceType("tap0")); + assertEquals(VxlanTunnel.class, getInterfaceType("vxlan0")); + assertEquals(VxlanGpeTunnel.class, getInterfaceType("vxlan_gpe0")); + assertEquals(VhostUser.class, getInterfaceType("VirtualEthernet0/0/0")); + assertEquals(EthernetCsmacd.class, getInterfaceType("eth0.0")); + assertEquals(EthernetCsmacd.class, getInterfaceType("local0")); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/L2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/L2CustomizerTest.java new file mode 100644 index 000000000..531e18d22 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/L2CustomizerTest.java @@ -0,0 +1,145 @@ +/* + * 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; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; +import io.fd.vpp.jvpp.core.dto.BridgeDomainSwIfDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; + +public class L2CustomizerTest extends ReaderCustomizerTest { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String BD_CTX_NAME = "bd-test-instance"; + private NamingContext interfaceContext; + private NamingContext bridgeDomainContext; + + public L2CustomizerTest() { + super(L2.class, VppInterfaceStateAugmentationBuilder.class); + } + + @Override + public void setUp() { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + bridgeDomainContext = new NamingContext("generatedBDName", BD_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new L2Customizer(api, interfaceContext, bridgeDomainContext); + } + + private InstanceIdentifier getL2Id(final String name) { + return InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(name)) + .augmentation( + VppInterfaceStateAugmentation.class).child(L2.class); + } + + private void whenBridgeDomainSwIfDumpThenReturn(final List bdSwIfList, + final List bridgeDomainDetailses) { + final BridgeDomainDetailsReplyDump reply = new BridgeDomainDetailsReplyDump(); + reply.bridgeDomainSwIfDetails = bdSwIfList; + reply.bridgeDomainDetails = bridgeDomainDetailses; + when(api.bridgeDomainSwIfDump(any(BridgeDomainDump.class))).thenReturn(future(reply)); + } + + + private BridgeDomainSwIfDetails generateBdSwIfDetails(final int ifId, final int bdId) { + final BridgeDomainSwIfDetails bdSwIfDetails = new BridgeDomainSwIfDetails(); + bdSwIfDetails.swIfIndex = ifId; + bdSwIfDetails.shg = 1; + bdSwIfDetails.bdId = bdId; + return bdSwIfDetails; + } + + private Interconnection generateInterconnection(final int ifId, final String bdName, final Boolean bvi) { + final BridgeBasedBuilder bbBuilder = new BridgeBasedBuilder(); + bbBuilder.setBridgeDomain(bdName); + bbBuilder.setSplitHorizonGroup((short) 1); + if (bvi != null) { + bbBuilder.setBridgedVirtualInterface(bvi); + } else { + bbBuilder.setBridgedVirtualInterface(false); // false is default + } + return bbBuilder.build(); + } + + @Test + public void testRead() throws Exception { + final Map cachedInterfaceDump = new HashMap<>(); + final int ifId = 1; + final int bdId = 1; + final String bdName = "bd001"; + final String ifName = "eth0.sub0"; + defineMapping(mappingContext, ifName, ifId, IFC_CTX_NAME); + defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); + + final SwInterfaceDetails ifaceDetails = new SwInterfaceDetails(); + ifaceDetails.subId = ifId; + cachedInterfaceDump.put(ifId, ifaceDetails); + cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump); + + // BVIinterfaceContext + whenBridgeDomainSwIfDumpThenReturn(Collections.singletonList(generateBdSwIfDetails(ifId, bdId)), + Collections.singletonList(generateBdDetails(ifId, bdId))); + + L2Builder builder = mock(L2Builder.class); + getCustomizer().readCurrentAttributes(getL2Id(ifName), builder, ctx); + + verify(builder).setInterconnection(generateInterconnection(ifId, bdName, true)); + + // Not BVI + whenBridgeDomainSwIfDumpThenReturn(Collections.singletonList(generateBdSwIfDetails(ifId, bdId)), + Collections.singletonList(generateBdDetails(99 /* Different ifc is marked as BVI in bd details */, bdId))); + + builder = mock(L2Builder.class); + getCustomizer().readCurrentAttributes(getL2Id(ifName), builder, ctx); + + verify(builder).setInterconnection(generateInterconnection(ifId, bdName, null)); + } + + private BridgeDomainDetails generateBdDetails(final int ifId, final int bdId) { + final BridgeDomainDetails bridgeDomainDetails = new BridgeDomainDetails(); + bridgeDomainDetails.bviSwIfIndex = ifId; + bridgeDomainDetails.bdId = bdId; + return bridgeDomainDetails; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizerTest.java new file mode 100644 index 000000000..1b79f518c --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizerTest.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; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.translate.util.TagRewriteOperation; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +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.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1q; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.RewriteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; + +public class RewriteCustomizerTest extends ReaderCustomizerTest { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final String VLAN_IF_NAME = "local0.1"; + private static final int VLAN_IF_INDEX = 11; + private static final int VLAN_ID = 1; + + private NamingContext interfacesContext; + + @Captor + private ArgumentCaptor> captor; + + public RewriteCustomizerTest() { + super(Rewrite.class, L2Builder.class); + } + + @Override + public void setUp() { + interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, VLAN_IF_NAME, VLAN_IF_INDEX, IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new RewriteCustomizer(api, interfacesContext); + } + + private InstanceIdentifier getVlanTagRewriteId(final String name, final long index) { + final Class> child = (Class)Rewrite.class; + final InstanceIdentifier id = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(name)).augmentation( + SubinterfaceStateAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(index)) + .child(child); + return id; + } + + @Test + public void testRead() throws ReadFailedException { + final Map cachedInterfaceDump = new HashMap<>(); + + final SwInterfaceDetails ifaceDetails = new SwInterfaceDetails(); + ifaceDetails.subId = VLAN_ID; + ifaceDetails.interfaceName = VLAN_IF_NAME.getBytes(); + ifaceDetails.vtrOp = TagRewriteOperation.translate_2_to_2.ordinal(); + ifaceDetails.subNumberOfTags = 2; + ifaceDetails.vtrTag1 = 123; + ifaceDetails.vtrTag2 = 321; + ifaceDetails.vtrPushDot1Q = 1; + cachedInterfaceDump.put(VLAN_IF_INDEX, ifaceDetails); + cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump); + + final RewriteBuilder builder = mock(RewriteBuilder.class); + + getCustomizer().readCurrentAttributes(getVlanTagRewriteId(IF_NAME, VLAN_ID), builder, ctx); + + verify(builder).setVlanType(_802dot1q.class); + verify(builder).setPopTags((short) 2); + + verify(builder).setPushTags(captor.capture()); + final List tags = captor.getValue(); + assertEquals(ifaceDetails.subNumberOfTags, tags.size()); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizerTest.java new file mode 100644 index 000000000..802d040dc --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizerTest.java @@ -0,0 +1,129 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import io.fd.hc2vpp.common.test.util.InterfaceDumpHelper; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfacesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.VlanTagged; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; + +public class SubInterfaceCustomizerTest extends ListReaderCustomizerTest implements + InterfaceDumpHelper { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String SUPER_IF_NAME = "local0"; + private static final int SUPER_IF_INDEX = 1; + private static final String VLAN_IF_NAME = "local0.1"; + private static final int VLAN_IF_ID = 1; + private static final int VLAN_IF_INDEX = 11; + + private NamingContext interfacesContext; + + public SubInterfaceCustomizerTest() { + super(SubInterface.class, SubInterfacesBuilder.class); + } + + @Override + public void setUp() { + interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, SUPER_IF_NAME, SUPER_IF_INDEX, IFC_CTX_NAME); + defineMapping(mappingContext, VLAN_IF_NAME, VLAN_IF_INDEX, IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new SubInterfaceCustomizer(api, interfacesContext); + } + + private InstanceIdentifier getSubInterfaceId(final String name, final long id) { + return InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(name)).augmentation( + SubinterfaceStateAugmentation.class).child( + SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(id)); + } + + @Test + public void testRead() throws ReadFailedException { + final Map cachedInterfaceDump = new HashMap<>(); + + final SwInterfaceDetails ifaceDetails = new SwInterfaceDetails(); + ifaceDetails.subId = VLAN_IF_ID; + ifaceDetails.interfaceName = VLAN_IF_NAME.getBytes(); + ifaceDetails.subDot1Ad = 1; + defineMapping(mappingContext, SUPER_IF_NAME, SUPER_IF_INDEX, IFC_CTX_NAME); + defineMapping(mappingContext, VLAN_IF_NAME, VLAN_IF_INDEX, IFC_CTX_NAME); + ifaceDetails.subNumberOfTags = 2; + ifaceDetails.subOuterVlanIdAny = 1; + ifaceDetails.subInnerVlanIdAny = 1; + ifaceDetails.subExactMatch = 1; + cachedInterfaceDump.put(VLAN_IF_INDEX, ifaceDetails); + cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump); + + final SubInterfaceBuilder builder = mock(SubInterfaceBuilder.class); + getCustomizer().readCurrentAttributes(getSubInterfaceId(SUPER_IF_NAME, VLAN_IF_ID), builder, ctx); + + verify(builder).setIdentifier((long) VLAN_IF_ID); + + ArgumentCaptor tagCaptor = ArgumentCaptor.forClass(Tags.class); + verify(builder).setTags(tagCaptor.capture()); + assertEquals(ifaceDetails.subNumberOfTags, tagCaptor.getValue().getTag().size()); + + ArgumentCaptor matchCaptor = ArgumentCaptor.forClass(Match.class); + verify(builder).setMatch(matchCaptor.capture()); + final VlanTagged matchType = (VlanTagged)matchCaptor.getValue().getMatchType(); + assertTrue(matchType.getVlanTagged().isMatchExactTags()); + } + + @Test + public void testGetAllIds() throws Exception { + final SwInterfaceDetails iface = new SwInterfaceDetails(); + iface.interfaceName = VLAN_IF_NAME.getBytes(); + iface.swIfIndex = VLAN_IF_INDEX; + iface.subId = VLAN_IF_ID; + iface.supSwIfIndex = SUPER_IF_INDEX; + whenSwInterfaceDumpThenReturn(api, iface); + + final List allIds = + getCustomizer().getAllIds(getSubInterfaceId(SUPER_IF_NAME, VLAN_IF_ID), ctx); + + assertEquals(1, allIds.size()); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2CustomizerTest.java new file mode 100644 index 000000000..fc7d8e853 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2CustomizerTest.java @@ -0,0 +1,80 @@ +/* + * 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; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceL2CustomizerTest extends ReaderCustomizerTest { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String BD_CTX_NAME = "bd-test-instance"; + private NamingContext interfaceContext; + private NamingContext bridgeDomainContext; + + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUB_IF_NAME = "local0.1"; + private static final long SUB_IF_ID = 1; + private static final int SUB_IF_INDEX = 11; + private InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceStateAugmentation.class) + .child(SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)).child(L2.class); + + public SubInterfaceL2CustomizerTest() { + super(L2.class, SubInterfaceBuilder.class); + } + + @Override + protected void setUp() { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + bridgeDomainContext = new NamingContext("generatedBDName", BD_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + defineMapping(mappingContext, SUB_IF_NAME, SUB_IF_INDEX, IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new SubInterfaceL2Customizer(api, interfaceContext, bridgeDomainContext); + } + + @Test(expected = ReadFailedException.class) + public void testReadFailed() throws ReadFailedException { + final L2Builder builder = mock(L2Builder.class); + when(api.swInterfaceDump(any())).thenReturn(failedFuture()); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizerTest.java new file mode 100644 index 000000000..c9de7102a --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizerTest.java @@ -0,0 +1,98 @@ +/* + * 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; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import io.fd.hc2vpp.common.test.util.InterfaceDumpHelper; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Tap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.TapBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetailsReplyDump; + +public class TapCustomizerTest extends ReaderCustomizerTest implements InterfaceDumpHelper { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IF_NAME = "tap1"; + private static final String TAP_NAME = "testTapName"; + private static final int IF_INDEX = 1; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(VppInterfaceStateAugmentation.class).child(Tap.class); + private NamingContext interfaceContext; + + public TapCustomizerTest() { + super(Tap.class, VppInterfaceStateAugmentationBuilder.class); + } + + @Override + protected void setUp() throws Exception { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + whenSwInterfaceDumpThenReturn(api, ifaceDetails()); + } + + private SwInterfaceDetails ifaceDetails() { + final SwInterfaceDetails details = new SwInterfaceDetails(); + details.swIfIndex = IF_INDEX; + details.interfaceName = IF_NAME.getBytes(); + return details; + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new TapCustomizer(api, interfaceContext); + } + + @Test + public void testRead() throws ReadFailedException { + final TapBuilder builder = mock(TapBuilder.class); + when(api.swInterfaceTapDump(any())).thenReturn(future(tapDump())); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + verify(builder).setTapName(TAP_NAME); + } + + @Test(expected = ReadFailedException.class) + public void testReadFailed() throws ReadFailedException { + when(api.swInterfaceTapDump(any())).thenReturn(failedFuture()); + getCustomizer().readCurrentAttributes(IID, mock(TapBuilder.class), ctx); + } + + private SwInterfaceTapDetailsReplyDump tapDump() { + final SwInterfaceTapDetailsReplyDump reply = new SwInterfaceTapDetailsReplyDump(); + final SwInterfaceTapDetails details = new SwInterfaceTapDetails(); + details.devName = TAP_NAME.getBytes(); + details.swIfIndex = IF_INDEX; + reply.swInterfaceTapDetails.add(details); + return reply; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizerTest.java new file mode 100644 index 000000000..57655db73 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizerTest.java @@ -0,0 +1,115 @@ +/* + * 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; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import io.fd.hc2vpp.common.test.util.InterfaceDumpHelper; +import java.math.BigInteger; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUserRole; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUser; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUserBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetailsReplyDump; + +public class VhostUserCustomizerTest extends ReaderCustomizerTest implements + InterfaceDumpHelper { + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IF_NAME = "VirtualEthernet1"; + private static final int IF_INDEX = 1; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(VppInterfaceStateAugmentation.class).child(VhostUser.class); + + private NamingContext interfaceContext; + + public VhostUserCustomizerTest() { + super(VhostUser.class, VppInterfaceStateAugmentationBuilder.class); + } + + @Override + protected void setUp() throws Exception { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + whenSwInterfaceDumpThenReturn(api, ifaceDetails()); + } + + private SwInterfaceDetails ifaceDetails() { + final SwInterfaceDetails details = new SwInterfaceDetails(); + details.swIfIndex = IF_INDEX; + details.interfaceName = IF_NAME.getBytes(); + return details; + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new VhostUserCustomizer(api, interfaceContext); + } + + @Test + public void testRead() throws ReadFailedException { + final VhostUserBuilder builder = mock(VhostUserBuilder.class); + when(api.swInterfaceVhostUserDump(any())).thenReturn(future(vhostDump())); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + verifyVhostBuilder(builder); + } + + @Test(expected = ReadFailedException.class) + public void testReadFailed() throws ReadFailedException { + when(api.swInterfaceVhostUserDump(any())).thenReturn(failedFuture()); + getCustomizer().readCurrentAttributes(IID, mock(VhostUserBuilder.class), ctx); + } + + private SwInterfaceVhostUserDetailsReplyDump vhostDump() { + final SwInterfaceVhostUserDetailsReplyDump reply = new SwInterfaceVhostUserDetailsReplyDump(); + final SwInterfaceVhostUserDetails details = new SwInterfaceVhostUserDetails(); + details.swIfIndex = IF_INDEX; + details.interfaceName = IF_NAME.getBytes(); + details.isServer = 1; + details.features = 2; + details.numRegions = 3; + details.sockFilename = "socketName".getBytes(); + details.virtioNetHdrSz = 4; + details.sockErrno = 5; + reply.swInterfaceVhostUserDetails.add(details); + return reply; + } + + private void verifyVhostBuilder(final VhostUserBuilder builder) { + verify(builder).setRole(VhostUserRole.Server); + verify(builder).setFeatures(BigInteger.valueOf(2)); + verify(builder).setNumMemoryRegions(3L); + verify(builder).setSocket("socketName"); + verify(builder).setVirtioNetHdrSize(4L); + verify(builder).setConnectError("5"); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizerTest.java new file mode 100644 index 000000000..d59d13672 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizerTest.java @@ -0,0 +1,133 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import com.google.common.collect.Lists; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Vxlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetails; +import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.VxlanTunnelDump; + +public class VxlanCustomizerTest extends ReaderCustomizerTest { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IF_NAME = "ifc1"; + private static final int IF_INDEX = 0; + + private NamingContext interfacesContext; + static final InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(VppInterfaceStateAugmentation.class).child(Vxlan.class); + + public VxlanCustomizerTest() { + super(Vxlan.class, VppInterfaceStateAugmentationBuilder.class); + } + + @Override + public void setUp() throws UnknownHostException, VppInvocationException { + interfacesContext = new NamingContext("vxlan-tunnel", IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + + final SwInterfaceDetails v = new SwInterfaceDetails(); + v.interfaceName = "vxlan-tunnel4".getBytes(); + final Map map = new HashMap<>(); + map.put(0, v); + cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, map); + + final VxlanTunnelDetailsReplyDump value = new VxlanTunnelDetailsReplyDump(); + final VxlanTunnelDetails vxlanTunnelDetails = new VxlanTunnelDetails(); + vxlanTunnelDetails.isIpv6 = 0; + vxlanTunnelDetails.decapNextIndex = 1; + vxlanTunnelDetails.dstAddress = InetAddress.getByName("1.2.3.4").getAddress(); + vxlanTunnelDetails.srcAddress = InetAddress.getByName("1.2.3.5").getAddress(); + vxlanTunnelDetails.encapVrfId = 55; + vxlanTunnelDetails.swIfIndex = 0; + vxlanTunnelDetails.vni = 9; + value.vxlanTunnelDetails = Lists.newArrayList(vxlanTunnelDetails); + doReturn(future(value)).when(api).vxlanTunnelDump(any(VxlanTunnelDump.class)); + } + + @Test + public void testReadCurrentAttributes() throws Exception { + final VxlanBuilder builder = getCustomizer().getBuilder(IID); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + + assertEquals(9, builder.getVni().getValue().intValue()); + assertEquals(55, builder.getEncapVrfId().intValue()); + + assertNull(builder.getSrc().getIpv6Address()); + assertNotNull(builder.getSrc().getIpv4Address()); + assertEquals("1.2.3.5", builder.getSrc().getIpv4Address().getValue()); + + assertNull(builder.getDst().getIpv6Address()); + assertNotNull(builder.getDst().getIpv4Address()); + assertEquals("1.2.3.4", builder.getDst().getIpv4Address().getValue()); + + verify(api).vxlanTunnelDump(any(VxlanTunnelDump.class)); + } + + @Test(expected = NullPointerException.class) + public void testReadCurrentAttributesVppNameNotCached() throws Exception { + InterfaceCustomizer.getCachedInterfaceDump(cache).remove(0); + + final VxlanBuilder builder = getCustomizer().getBuilder(IID); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + } + + @Test + public void testReadCurrentAttributesWrongType() throws Exception { + final SwInterfaceDetails v = new SwInterfaceDetails(); + v.interfaceName = "tap-2".getBytes(); + InterfaceCustomizer.getCachedInterfaceDump(cache).put(0, v); + + final VxlanBuilder builder = getCustomizer().getBuilder(IID); + getCustomizer().readCurrentAttributes(IID, builder, ctx); + + // Should be ignored + verifyZeroInteractions(api); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new VxlanCustomizer(api, interfacesContext); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizerTest.java new file mode 100644 index 000000000..e0abd51ec --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizerTest.java @@ -0,0 +1,278 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import com.google.common.collect.Lists; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpe; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpeBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetails; +import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDump; + +public class VxlanGpeCustomizerTest extends ReaderCustomizerTest { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IF_NAME = "ifc2"; + private static final int IF_INDEX = 0; + + private NamingContext interfacesContext; + private static final InstanceIdentifier VXLAN_GPE_ID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(VppInterfaceStateAugmentation.class).child(VxlanGpe.class); + + public VxlanGpeCustomizerTest() { + super(VxlanGpe.class, VppInterfaceStateAugmentationBuilder.class); + } + + @Override + public void setUp() throws UnknownHostException, VppBaseCallException { + interfacesContext = new NamingContext("vxlan_gpe_inf", IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + + final SwInterfaceDetails v = new SwInterfaceDetails(); + v.interfaceName = "vxlan_gpe_inf2".getBytes(); + final Map map = new HashMap<>(); + map.put(0, v); + cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, map); + + final VxlanGpeTunnelDetailsReplyDump value = new VxlanGpeTunnelDetailsReplyDump(); + final VxlanGpeTunnelDetails vxlanGpeTunnelDetails = new VxlanGpeTunnelDetails(); + vxlanGpeTunnelDetails.isIpv6 = 0; + vxlanGpeTunnelDetails.local = InetAddress.getByName("1.2.3.4").getAddress(); + vxlanGpeTunnelDetails.remote = InetAddress.getByName("1.2.3.5").getAddress(); + vxlanGpeTunnelDetails.vni = 9; + vxlanGpeTunnelDetails.protocol = 1; + vxlanGpeTunnelDetails.encapVrfId = 55; + vxlanGpeTunnelDetails.decapVrfId = 66; + vxlanGpeTunnelDetails.swIfIndex = 0; + value.vxlanGpeTunnelDetails = Lists.newArrayList(vxlanGpeTunnelDetails); + doReturn(future(value)).when(api).vxlanGpeTunnelDump(any(VxlanGpeTunnelDump.class)); + } + + @Test + public void testReadCurrentAttributes() throws Exception { + final VxlanGpeBuilder builder = getCustomizer().getBuilder(VXLAN_GPE_ID); + getCustomizer().readCurrentAttributes(VXLAN_GPE_ID, builder, ctx); + + assertNull(builder.getLocal().getIpv6Address()); + assertNotNull(builder.getLocal().getIpv4Address()); + assertEquals("1.2.3.4", builder.getLocal().getIpv4Address().getValue()); + + assertNull(builder.getRemote().getIpv6Address()); + assertNotNull(builder.getRemote().getIpv4Address()); + assertEquals("1.2.3.5", builder.getRemote().getIpv4Address().getValue()); + + assertEquals(9, builder.getVni().getValue().intValue()); + assertEquals(1, builder.getNextProtocol().getIntValue()); + assertEquals(55, builder.getEncapVrfId().intValue()); + assertEquals(66, builder.getDecapVrfId().intValue()); + + verify(api).vxlanGpeTunnelDump(any(VxlanGpeTunnelDump.class)); + } + + @Test(expected = NullPointerException.class) + public void testReadCurrentAttributesVppNameNotCached() throws Exception { + InterfaceCustomizer.getCachedInterfaceDump(cache).remove(0); + + final VxlanGpeBuilder builder = getCustomizer().getBuilder(VXLAN_GPE_ID); + getCustomizer().readCurrentAttributes(VXLAN_GPE_ID, builder, ctx); + } + + @Test + public void testReadCurrentAttributesWrongType() throws Exception { + final SwInterfaceDetails v = new SwInterfaceDetails(); + v.interfaceName = "tap-3".getBytes(); + InterfaceCustomizer.getCachedInterfaceDump(cache).put(0, v); + + final VxlanGpeBuilder builder = getCustomizer().getBuilder(VXLAN_GPE_ID); + getCustomizer().readCurrentAttributes(VXLAN_GPE_ID, builder, ctx); + + // Should be ignored + verifyZeroInteractions(api); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new VxlanGpeCustomizer(api, interfacesContext); + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java new file mode 100644 index 000000000..6948302e8 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java @@ -0,0 +1,99 @@ +/* + * 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.acl.ingress; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AclCustomizerTest extends ReaderCustomizerTest { + + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final int TABLE_INDEX = 123; + private static final String TABLE_NAME = "table123"; + private static final InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(VppInterfaceStateAugmentation.class).child(Acl.class).child(Ingress.class); + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + + private NamingContext interfaceContext; + + @Mock + private VppClassifierContextManager classifyTableContext; + + public AclCustomizerTest() { + super(Ingress.class, AclBuilder.class); + } + + @Override + public void setUp() { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new AclCustomizer(api, interfaceContext, classifyTableContext); + } + + @Test + public void testRead() throws ReadFailedException { + final IngressBuilder builder = mock(IngressBuilder.class); + + final ClassifyTableByInterfaceReply reply = new ClassifyTableByInterfaceReply(); + reply.l2TableId = TABLE_INDEX; + reply.ip4TableId = ~0; + reply.ip6TableId = ~0; + when(api.classifyTableByInterface(any())).thenReturn(future(reply)); + + when(classifyTableContext.getTableName(TABLE_INDEX, mappingContext)).thenReturn(TABLE_NAME); + + getCustomizer().readCurrentAttributes(IID, builder, ctx); + + verify(builder).setL2Acl(new L2AclBuilder().setClassifyTable(TABLE_NAME).build()); + verify(builder).setIp4Acl(null); + verify(builder).setIp6Acl(null); + } + + @Test(expected = ReadFailedException.class) + public void testReadFailed() throws ReadFailedException { + when(api.classifyTableByInterface(any())).thenReturn(failedFuture()); + getCustomizer().readCurrentAttributes(IID, mock(IngressBuilder.class), ctx); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java new file mode 100644 index 000000000..9dbb20fb0 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java @@ -0,0 +1,108 @@ +/* + * 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.acl.ingress; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceAclCustomizerTest extends ReaderCustomizerTest { + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUB_IF_NAME = "local0.1"; + private static final long SUB_IF_ID = 1; + private static final int SUB_IF_INDEX = 11; + private static final int TABLE_INDEX = 123; + private static final String TABLE_NAME = "table123"; + + private static final InstanceIdentifier IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceStateAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)).child(Acl.class).child(Ingress.class); + + private NamingContext interfaceContext; + + @Mock + private VppClassifierContextManager classifyTableContext; + + public SubInterfaceAclCustomizerTest() { + super(Ingress.class, AclBuilder.class); + } + + @Override + protected void setUp() throws Exception { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + defineMapping(mappingContext, SUB_IF_NAME, SUB_IF_INDEX, IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new SubInterfaceAclCustomizer(api, interfaceContext, classifyTableContext); + } + + @Test + public void testRead() throws ReadFailedException { + final IngressBuilder builder = mock(IngressBuilder.class); + + final ClassifyTableByInterfaceReply reply = new ClassifyTableByInterfaceReply(); + reply.swIfIndex = SUB_IF_INDEX; + reply.l2TableId = ~0; + reply.ip4TableId = TABLE_INDEX; + reply.ip6TableId = TABLE_INDEX; + when(api.classifyTableByInterface(any())).thenReturn(future(reply)); + + when(classifyTableContext.getTableName(TABLE_INDEX, mappingContext)).thenReturn(TABLE_NAME); + + getCustomizer().readCurrentAttributes(IID, builder, ctx); + + verify(builder).setL2Acl(null); + verify(builder).setIp4Acl(new Ip4AclBuilder().setClassifyTable(TABLE_NAME).build()); + verify(builder).setIp6Acl(new Ip6AclBuilder().setClassifyTable(TABLE_NAME).build()); + } + + @Test(expected = ReadFailedException.class) + public void testReadFailed() throws ReadFailedException { + when(api.classifyTableByInterface(any())).thenReturn(failedFuture()); + getCustomizer().readCurrentAttributes(IID, mock(IngressBuilder.class), ctx); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java new file mode 100644 index 000000000..a2eda9157 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java @@ -0,0 +1,284 @@ +/* + * 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.ip; + + +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.honeycomb.translate.util.read.cache.CacheKeyFactory; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; +import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import io.fd.vpp.jvpp.core.dto.IpAddressDetails; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.IpAddressDump; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; +import org.hamcrest.Matchers; +import org.junit.Test; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLength; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest implements + Ipv4Translator { + + private static final String IFACE_NAME = "eth0"; + private static final String IFACE_2_NAME = "eth1"; + private static final int IFACE_ID = 1; + private static final int IFACE_2_ID = 2; + private static final String IFC_CTX_NAME = "ifc-test-instance"; + + private NamingContext interfacesContext; + private InstanceIdentifier
ifaceOneAddressOneIdentifier; + private InstanceIdentifier
ifaceTwoAddressOneIdentifier; + private CacheKeyFactory cacheKeyFactory; + + public Ipv4AddressCustomizerTest() { + super(Address.class, Ipv4Builder.class); + } + + @Override + public void setUp() { + interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + defineMapping(mappingContext, IFACE_2_NAME, IFACE_2_ID, IFC_CTX_NAME); + + ifaceOneAddressOneIdentifier = + InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(Interface2.class) + .child(Ipv4.class) + .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); + ifaceTwoAddressOneIdentifier = + InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(IFACE_2_NAME)) + .augmentation(Interface2.class) + .child(Ipv4.class) + .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); + + // to simulate complex key + cacheKeyFactory = new IdentifierCacheKeyFactory(ImmutableSet.of(Interface.class)); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new Ipv4AddressCustomizer(api, interfacesContext); + } + + private static InstanceIdentifier
getId(final String address, final String ifaceName) { + return InstanceIdentifier.builder(InterfacesState.class) + .child(Interface.class, new InterfaceKey(ifaceName)) + .augmentation(Interface2.class) + .child(Ipv4.class) + .child(Address.class, new AddressKey(new Ipv4AddressNoZone(new Ipv4Address(address)))) + .build(); + } + + @Test + public void testReadCurrentAttributesFor2Ifcs() throws ReadFailedException { + //changed to mock to not store first dumped data(otherwise that double thenReturn on line 118 is not gonna work) + + IpAddressDetails detail1 = new IpAddressDetails(); + IpAddressDetails detail2 = new IpAddressDetails(); + + detail1.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detail2.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.2")))); + + IpAddressDetailsReplyDump reply = new IpAddressDetailsReplyDump(); + reply.ipAddressDetails = ImmutableList.of(detail1); + IpAddressDetailsReplyDump reply2 = new IpAddressDetailsReplyDump(); + reply2.ipAddressDetails = ImmutableList.of(detail2); + + CompletableFuture future = new CompletableFuture<>(); + future.complete(reply); + CompletableFuture future2 = new CompletableFuture<>(); + future2.complete(reply2); + + when(api.ipAddressDump(Mockito.any(IpAddressDump.class))).thenReturn(future).thenReturn(future2) + .thenReturn(future).thenReturn(future2); + when(api.ipAddressDump(Mockito.any(IpAddressDump.class))).thenReturn(future(reply)).thenReturn(future(reply2)) + .thenReturn(future(reply)).thenReturn(future(reply2)); + when(ctx.getModificationCache()).thenReturn(cache); + + + final InstanceIdentifier
id = getId("192.168.2.1", IFACE_NAME); + final InstanceIdentifier
id2 = getId("192.168.2.2", IFACE_2_NAME); + + final List ifc1Ids = getCustomizer().getAllIds(id, ctx); + assertThat(ifc1Ids.size(), is(1)); + assertThat(ifc1Ids, Matchers.hasItem(new AddressKey(new Ipv4AddressNoZone("192.168.2.1")))); + final List ifc2Ids = getCustomizer().getAllIds(id2, ctx); + assertThat(ifc2Ids.size(), is(1)); + assertThat(ifc2Ids, Matchers.hasItem(new AddressKey(new Ipv4AddressNoZone("192.168.2.2")))); + + AddressBuilder builder = new AddressBuilder(); + getCustomizer().readCurrentAttributes(id, builder, ctx); + assertEquals(builder.getIp().getValue(), "192.168.2.1"); + builder = new AddressBuilder(); + getCustomizer().readCurrentAttributes(id2, builder, ctx); + assertEquals(builder.getIp().getValue(), "192.168.2.2"); + } + + @Test + public void testReadCurrentAttributesSuccessfull() throws ReadFailedException { + IpAddressDetails detail1 = new IpAddressDetails(); + IpAddressDetails detail2 = new IpAddressDetails(); + IpAddressDetails detail3 = new IpAddressDetails(); + + detail1.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detail2.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.2")))); + detail3.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.3")))); + + IpAddressDetailsReplyDump reply = new IpAddressDetailsReplyDump(); + reply.ipAddressDetails = ImmutableList.of(detail1, detail2, detail3); + when(api.ipAddressDump(Mockito.any(IpAddressDump.class))).thenReturn(future(reply)); + when(ctx.getModificationCache()).thenReturn(cache); + + final AddressBuilder builder = new AddressBuilder(); + final InstanceIdentifier
id = getId("192.168.2.1", IFACE_NAME); + + getCustomizer().readCurrentAttributes(id, builder, ctx); + + assertEquals("192.168.2.1", builder.getIp().getValue()); + } + + @Test + public void testGetAllIdsFromSuccessfull() throws ReadFailedException { + IpAddressDetails detail1 = new IpAddressDetails(); + IpAddressDetails detail2 = new IpAddressDetails(); + IpAddressDetails detail3 = new IpAddressDetails(); + + detail1.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detail2.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.2")))); + detail3.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.3")))); + + IpAddressDetailsReplyDump reply = new IpAddressDetailsReplyDump(); + reply.ipAddressDetails = ImmutableList.of(detail1, detail2, detail3); + when(api.ipAddressDump(Mockito.any(IpAddressDump.class))).thenReturn(future(reply)); + when(ctx.getModificationCache()).thenReturn(cache); + + final InstanceIdentifier
id = getId("192.168.2.1", IFACE_NAME); + + List ids = getCustomizer().getAllIds(id, ctx).stream() + .map(key -> key.getIp()) + .collect(Collectors.toList()); + + assertEquals(3, ids.size()); + assertEquals(true, "192.168.2.1".equals(ids.get(0).getValue())); + assertEquals(true, "192.168.2.2".equals(ids.get(1).getValue())); + assertEquals(true, "192.168.2.3".equals(ids.get(2).getValue())); + } + + @Test + public void testCachingScopeSpecificRequest() throws ReadFailedException { + fillCacheForTwoIfaces(); + final AddressBuilder ifaceOneAddressBuilder = new AddressBuilder(); + final AddressBuilder ifaceTwoAddressBuilder = new AddressBuilder(); + + getCustomizer().readCurrentAttributes(ifaceOneAddressOneIdentifier, ifaceOneAddressBuilder, ctx); + getCustomizer().readCurrentAttributes(ifaceTwoAddressOneIdentifier, ifaceTwoAddressBuilder, ctx); + + // addresses have caching scope of parent interface, so returned address should have respective prefix lengths + assertEquals("192.168.2.1", ifaceOneAddressBuilder.getIp().getValue()); + assertTrue(ifaceOneAddressBuilder.getSubnet() instanceof PrefixLength); + assertEquals(22, PrefixLength.class.cast(ifaceOneAddressBuilder.getSubnet()).getPrefixLength().intValue()); + + assertEquals("192.168.2.1", ifaceTwoAddressBuilder.getIp().getValue()); + assertTrue(ifaceTwoAddressBuilder.getSubnet() instanceof PrefixLength); + assertEquals(23, PrefixLength.class.cast(ifaceTwoAddressBuilder.getSubnet()).getPrefixLength().intValue()); + } + + @Test + public void testCachingScopeGetAll() throws ReadFailedException { + fillCacheForFirstIfaceSecondEmpty(); + + final List keysForIfaceOne = getCustomizer().getAllIds(ifaceOneAddressOneIdentifier, ctx); + assertThat(keysForIfaceOne, hasSize(1)); + final AddressKey keyIfaceOne = keysForIfaceOne.get(0); + assertEquals("192.168.2.1", keyIfaceOne.getIp().getValue()); + + final List keysForIfaceTwo = getCustomizer().getAllIds(ifaceTwoAddressOneIdentifier, ctx); + assertThat(keysForIfaceTwo, is(empty())); + } + + private void fillCacheForTwoIfaces() { + IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); + IpAddressDetails detailIfaceTwoAddressOne = new IpAddressDetails(); + IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); + IpAddressDetailsReplyDump replyIfaceTwo = new IpAddressDetailsReplyDump(); + + replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); + replyIfaceTwo.ipAddressDetails = Arrays.asList(detailIfaceTwoAddressOne); + + detailIfaceOneAddressOne.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detailIfaceOneAddressOne.prefixLength = 22; + + detailIfaceTwoAddressOne.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detailIfaceTwoAddressOne.prefixLength = 23; + + cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); + cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), replyIfaceTwo); + } + + private void fillCacheForFirstIfaceSecondEmpty() { + IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); + IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); + replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); + + detailIfaceOneAddressOne.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detailIfaceOneAddressOne.prefixLength = 22; + + cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); + cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), new IpAddressDetailsReplyDump()); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4CustomizerTest.java new file mode 100644 index 000000000..1bfb62771 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4CustomizerTest.java @@ -0,0 +1,44 @@ +/* + * 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.ip; + +import static org.mockito.Mockito.verifyZeroInteractions; + +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; + +public class Ipv4CustomizerTest extends ReaderCustomizerTest { + + public Ipv4CustomizerTest() { + super(Ipv4.class, Interface2Builder.class); + } + + @Test + public void testReadCurrentAttributes() throws Exception { + customizer.readCurrentAttributes(null, null, ctx); + verifyZeroInteractions(api); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new Ipv4Customizer(api); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java new file mode 100644 index 000000000..cecc70235 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java @@ -0,0 +1,247 @@ +/* + * 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.ip; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableSet; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.util.read.cache.CacheKeyFactory; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; +import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import io.fd.vpp.jvpp.core.dto.IpAddressDetails; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import java.util.Arrays; +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceIpv4AddressCustomizerTest extends ListReaderCustomizerTest + implements Ipv4Translator { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IF_NAME = "local0"; + private static final int IF_INDEX = 1; + private static final String SUB_IF_NAME = "local0.1"; + private static final String SUB_IF_2_NAME = "local0.2"; + private static final long SUB_IF_ID = 1; + private static final int SUB_IF_INDEX = 11; + private static final int SUB_IF_2_INDEX = 12; + private static final InstanceIdentifier IP4_IID = + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceStateAugmentation.class) + .child(SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)) + .child(Ipv4.class); + private InstanceIdentifier
ifaceOneAddressOneIdentifier; + private InstanceIdentifier
ifaceTwoAddressOneIdentifier; + private CacheKeyFactory cacheKeyFactory; + private static final Ipv4AddressNoZone IP1 = new Ipv4AddressNoZone("10.1.1.1"); + private static final Ipv4AddressNoZone IP2 = new Ipv4AddressNoZone("10.1.1.2"); + private static final short PREFIX_LENGTH = 16; + + private NamingContext interfaceContext; + + public SubInterfaceIpv4AddressCustomizerTest() { + super(Address.class, Ipv4Builder.class); + } + + @Override + protected void setUp() throws Exception { + interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + + ifaceOneAddressOneIdentifier = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceStateAugmentation.class) + .child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(1L)) + .child(Ipv4.class) + .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); + ifaceTwoAddressOneIdentifier = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceStateAugmentation.class) + .child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(2L)) + .child(Ipv4.class) + .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); + + // to simulate complex key + cacheKeyFactory = new IdentifierCacheKeyFactory(ImmutableSet.of(SubInterface.class)); + + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); + defineMapping(mappingContext, SUB_IF_NAME, SUB_IF_INDEX, IFC_CTX_NAME); + defineMapping(mappingContext, SUB_IF_2_NAME, SUB_IF_2_INDEX, IFC_CTX_NAME); + } + + @Override + protected ListReaderCustomizer initCustomizer() { + return new SubInterfaceIpv4AddressCustomizer(api, interfaceContext); + } + + private static InstanceIdentifier
getId() { + return IP4_IID.child(Address.class); + } + + private static InstanceIdentifier
getId(final Ipv4AddressNoZone ip) { + return IP4_IID.child(Address.class, new AddressKey(ip)); + } + + @Test + public void testRead() throws ReadFailedException { + final AddressBuilder builder = mock(AddressBuilder.class); + when(api.ipAddressDump(any())).thenReturn(future(dump())); + getCustomizer().readCurrentAttributes(getId(IP2), builder, ctx); + verify(builder).setIp(IP2); + verify(builder).setSubnet(new PrefixLengthBuilder().setPrefixLength(PREFIX_LENGTH).build()); + } + + @Test(expected = ReadFailedException.class) + public void testReadFailed() throws ReadFailedException { + when(api.ipAddressDump(any())).thenReturn(failedFuture()); + getCustomizer().readCurrentAttributes(getId(IP1), mock(AddressBuilder.class), ctx); + } + + @Test + public void testGetAllIds() throws ReadFailedException { + when(api.ipAddressDump(any())).thenReturn(future(dump())); + final List allIds = getCustomizer().getAllIds(getId(), ctx); + assertThat(allIds, hasSize(2)); + assertThat(allIds, containsInAnyOrder(new AddressKey(IP1), new AddressKey(IP2))); + } + + @Test(expected = ReadFailedException.class) + public void testGetAllIdsFailed() throws ReadFailedException { + when(api.ipAddressDump(any())).thenReturn(failedFuture()); + getCustomizer().getAllIds(getId(), ctx); + } + + @Test + public void testCacheScope() { + + } + + @Test + public void testCachingScopeSpecificRequest() throws ReadFailedException { + fillCacheForTwoIfaces(); + final AddressBuilder ifaceOneAddressBuilder = new AddressBuilder(); + final AddressBuilder ifaceTwoAddressBuilder = new AddressBuilder(); + + getCustomizer().readCurrentAttributes(ifaceOneAddressOneIdentifier, ifaceOneAddressBuilder, ctx); + getCustomizer().readCurrentAttributes(ifaceTwoAddressOneIdentifier, ifaceTwoAddressBuilder, ctx); + + // addresses have caching scope of parent interface, so returned address should have respective prefix lengths + assertEquals("192.168.2.1", ifaceOneAddressBuilder.getIp().getValue()); + assertTrue(ifaceOneAddressBuilder.getSubnet() instanceof PrefixLength); + assertEquals(22, PrefixLength.class.cast(ifaceOneAddressBuilder.getSubnet()).getPrefixLength().intValue()); + + assertEquals("192.168.2.1", ifaceTwoAddressBuilder.getIp().getValue()); + assertTrue(ifaceTwoAddressBuilder.getSubnet() instanceof PrefixLength); + assertEquals(23, PrefixLength.class.cast(ifaceTwoAddressBuilder.getSubnet()).getPrefixLength().intValue()); + } + + @Test + public void testCachingScopeGetAll() throws ReadFailedException { + fillCacheForFirstIfaceSecondEmpty(); + + final List keysForIfaceOne = getCustomizer().getAllIds(ifaceOneAddressOneIdentifier, ctx); + Assert.assertThat(keysForIfaceOne, hasSize(1)); + final AddressKey keyIfaceOne = keysForIfaceOne.get(0); + assertEquals("192.168.2.1", keyIfaceOne.getIp().getValue()); + + final List keysForIfaceTwo = getCustomizer().getAllIds(ifaceTwoAddressOneIdentifier, ctx); + Assert.assertThat(keysForIfaceTwo, is(empty())); + } + + private void fillCacheForTwoIfaces() { + IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); + IpAddressDetails detailIfaceTwoAddressOne = new IpAddressDetails(); + IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); + IpAddressDetailsReplyDump replyIfaceTwo = new IpAddressDetailsReplyDump(); + + replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); + replyIfaceTwo.ipAddressDetails = Arrays.asList(detailIfaceTwoAddressOne); + + detailIfaceOneAddressOne.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detailIfaceOneAddressOne.prefixLength = 22; + + detailIfaceTwoAddressOne.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detailIfaceTwoAddressOne.prefixLength = 23; + + cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); + cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), replyIfaceTwo); + } + + private void fillCacheForFirstIfaceSecondEmpty() { + IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); + IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); + replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); + + detailIfaceOneAddressOne.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detailIfaceOneAddressOne.prefixLength = 22; + + cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); + cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), new IpAddressDetailsReplyDump()); + } + + private IpAddressDetailsReplyDump dump() { + final IpAddressDetailsReplyDump reply = new IpAddressDetailsReplyDump(); + + final IpAddressDetails details1 = new IpAddressDetails(); + details1.ip = new byte[]{1, 1, 1, 10}; + details1.prefixLength = (byte) PREFIX_LENGTH; + reply.ipAddressDetails.add(details1); + + final IpAddressDetails details2 = new IpAddressDetails(); + details2.ip = new byte[]{2, 1, 1, 10}; + details2.prefixLength = (byte) PREFIX_LENGTH; + reply.ipAddressDetails.add(details2); + + return reply; + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java new file mode 100644 index 000000000..2fd959add --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java @@ -0,0 +1,35 @@ +/* + * 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.pbb; + +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteStateInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteStateBuilder; + +public class PbbRewriteStateCustomizerTest extends ReaderCustomizerTest { + + public PbbRewriteStateCustomizerTest() { + super(PbbRewriteState.class, PbbRewriteStateInterfaceAugmentationBuilder.class); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new PbbRewriteStateCustomizer(api); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/notification/InterfaceChangeNotificationProducerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/notification/InterfaceChangeNotificationProducerTest.java new file mode 100644 index 000000000..38c658895 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/notification/InterfaceChangeNotificationProducerTest.java @@ -0,0 +1,112 @@ +/* + * 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.notification; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import io.fd.honeycomb.notification.NotificationCollector; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.hc2vpp.common.test.util.NamingContextHelper; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.util.FutureProducer; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStateChange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStatus; +import io.fd.vpp.jvpp.core.callback.SwInterfaceSetFlagsNotificationCallback; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsNotification; +import io.fd.vpp.jvpp.core.dto.WantInterfaceEvents; +import io.fd.vpp.jvpp.core.dto.WantInterfaceEventsReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import io.fd.vpp.jvpp.core.notification.CoreNotificationRegistry; + +public class InterfaceChangeNotificationProducerTest implements FutureProducer, NamingContextHelper { + + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private static final String IFACE_NAME = "eth0"; + private static final int IFACE_ID = 0; + + @Mock + private FutureJVppCore jVpp; + private NamingContext namingContext = new NamingContext("test", IFC_CTX_NAME); + @Mock + private MappingContext mappingContext; + @Mock + private NotificationCollector collector; + @Mock + private CoreNotificationRegistry notificationRegistry; + @Mock + private AutoCloseable notificationListenerReg; + + private ArgumentCaptor callbackArgumentCaptor; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + doReturn(notificationRegistry).when(jVpp).getNotificationRegistry(); + callbackArgumentCaptor = ArgumentCaptor.forClass(SwInterfaceSetFlagsNotificationCallback.class); + doReturn(notificationListenerReg).when(notificationRegistry).registerSwInterfaceSetFlagsNotificationCallback( + callbackArgumentCaptor.capture()); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + doReturn(future(new WantInterfaceEventsReply())).when(jVpp).wantInterfaceEvents(any(WantInterfaceEvents.class)); + } + + @Test + public void testStart() throws Exception { + final InterfaceChangeNotificationProducer interfaceChangeNotificationProducer = + new InterfaceChangeNotificationProducer(jVpp, namingContext, mappingContext); + + interfaceChangeNotificationProducer.start(collector); + verify(jVpp).wantInterfaceEvents(any(WantInterfaceEvents.class)); + verify(jVpp).getNotificationRegistry(); + verify(notificationRegistry).registerSwInterfaceSetFlagsNotificationCallback(any( + SwInterfaceSetFlagsNotificationCallback.class)); + + interfaceChangeNotificationProducer.stop(); + verify(jVpp, times(2)).wantInterfaceEvents(any(WantInterfaceEvents.class)); + verify(notificationListenerReg).close(); + } + + @Test + public void testNotification() throws Exception { + final InterfaceChangeNotificationProducer interfaceChangeNotificationProducer = + new InterfaceChangeNotificationProducer(jVpp, namingContext, mappingContext); + + interfaceChangeNotificationProducer.start(collector); + + final SwInterfaceSetFlagsNotification swInterfaceSetFlagsNotification = new SwInterfaceSetFlagsNotification(); + swInterfaceSetFlagsNotification.deleted = 0; + swInterfaceSetFlagsNotification.swIfIndex = IFACE_ID; + swInterfaceSetFlagsNotification.adminUpDown = 1; + swInterfaceSetFlagsNotification.linkUpDown = 1; + callbackArgumentCaptor.getValue().onSwInterfaceSetFlagsNotification(swInterfaceSetFlagsNotification); + final ArgumentCaptor notificationCaptor = + ArgumentCaptor.forClass(InterfaceStateChange.class); + verify(collector).onNotification(notificationCaptor.capture()); + + assertEquals(IFACE_NAME, notificationCaptor.getValue().getName().getString()); + assertEquals(InterfaceStatus.Up, notificationCaptor.getValue().getAdminStatus()); + assertEquals(InterfaceStatus.Up, notificationCaptor.getValue().getOperStatus()); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/util/SubinterfaceUtilsTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/util/SubinterfaceUtilsTest.java new file mode 100644 index 000000000..fc08fbc59 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/util/SubinterfaceUtilsTest.java @@ -0,0 +1,32 @@ +/* + * 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.util; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class SubinterfaceUtilsTest { + + @Test + public void testGetSubInterfaceName() throws Exception { + final String superIfName = "GigabitEthernet0/9/0"; + final int subIfaceId = 123; + final String expectedSubIfaceName = "GigabitEthernet0/9/0.123"; + assertEquals(expectedSubIfaceName, SubInterfaceUtils.getSubInterfaceName(superIfName, subIfaceId)); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizerTest.java new file mode 100644 index 000000000..3377809b7 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizerTest.java @@ -0,0 +1,171 @@ +/* + * 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.vpp; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.BdIpMacAddDel; +import io.fd.vpp.jvpp.core.dto.BdIpMacAddDelReply; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.ArpTerminationTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class ArpTerminationTableEntryCustomizerTest extends WriterCustomizerTest { + private static final String BD_CTX_NAME = "bd-test-instance"; + private static final String IFC_CTX_NAME = "ifc-test-instance"; + + private static final String BD_NAME = "testBD0"; + private static final int BD_ID = 111; + private static final String IFACE_NAME = "eth0"; + private static final int IFACE_ID = 123; + private ArpTerminationTableEntryCustomizer customizer; + private byte[] ipAddressRaw; + private byte[] physAddressRaw; + private PhysAddress physAddress; + private IpAddress ipAddress; + private ArpTerminationTableEntry entry; + private InstanceIdentifier id; + + @Override + public void setUp() throws Exception { + customizer = new ArpTerminationTableEntryCustomizer(api, new NamingContext("generatedBdName", BD_CTX_NAME)); + + ipAddressRaw = new byte[]{1, 2, 3, 4}; + physAddressRaw = new byte[]{1, 2, 3, 4, 5, 6}; + physAddress = new PhysAddress("01:02:03:04:05:06"); + + ipAddress = new IpAddress(Ipv4AddressNoZone.getDefaultInstance("1.2.3.4")); + entry = generateArpEntry(ipAddress, physAddress); + id = getArpEntryId(ipAddress, physAddress); + + defineMapping(mappingContext, BD_NAME, BD_ID, BD_CTX_NAME); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + } + + private static InstanceIdentifier getArpEntryId(final IpAddress ipAddress, + final PhysAddress physAddress) { + return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(BD_NAME)) + .child(ArpTerminationTable.class) + .child(ArpTerminationTableEntry.class, new ArpTerminationTableEntryKey(ipAddress, physAddress)); + } + + private void whenBdIpMacAddDelThenSuccess() { + doReturn(future(new BdIpMacAddDelReply())).when(api).bdIpMacAddDel(any(BdIpMacAddDel.class)); + } + + private void whenBdIpMacAddDelThenFailure() { + doReturn(failedFuture()).when(api).bdIpMacAddDel(any(BdIpMacAddDel.class)); + } + + private BdIpMacAddDel generateBdIpMacAddDelRequest(final byte[] ipAddress, final byte[] macAddress, + final byte isAdd) { + final BdIpMacAddDel request = new BdIpMacAddDel(); + request.ipAddress = ipAddress; + request.macAddress = macAddress; + request.bdId = BD_ID; + request.isAdd = isAdd; + return request; + } + + private ArpTerminationTableEntry generateArpEntry(final IpAddress ipAddress, final PhysAddress physAddress) { + final ArpTerminationTableEntryBuilder entry = new ArpTerminationTableEntryBuilder(); + entry.setKey(new ArpTerminationTableEntryKey(ipAddress, physAddress)); + entry.setPhysAddress(physAddress); + entry.setIpAddress(ipAddress); + return entry.build(); + } + + private void verifyBdIpMacAddDelWasInvoked(final BdIpMacAddDel expected) throws + VppInvocationException { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(BdIpMacAddDel.class); + verify(api).bdIpMacAddDel(argumentCaptor.capture()); + final BdIpMacAddDel actual = argumentCaptor.getValue(); + assertArrayEquals(expected.macAddress, actual.macAddress); + assertArrayEquals(expected.ipAddress, actual.ipAddress); + assertEquals(expected.bdId, actual.bdId); + assertEquals(expected.isAdd, actual.isAdd); + } + + @Test + public void testCreate() throws Exception { + whenBdIpMacAddDelThenSuccess(); + customizer.writeCurrentAttributes(id, entry, writeContext); + verifyBdIpMacAddDelWasInvoked(generateBdIpMacAddDelRequest(ipAddressRaw, physAddressRaw, (byte) 1)); + } + + @Test + public void testCreateFailed() throws Exception { + whenBdIpMacAddDelThenFailure(); + try { + customizer.writeCurrentAttributes(id, entry, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyBdIpMacAddDelWasInvoked(generateBdIpMacAddDelRequest(ipAddressRaw, physAddressRaw, (byte) 1)); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdate() throws Exception { + customizer.updateCurrentAttributes(InstanceIdentifier.create(ArpTerminationTableEntry.class), + mock(ArpTerminationTableEntry.class), + mock(ArpTerminationTableEntry.class), writeContext); + } + + @Test + public void testDelete() throws Exception { + whenBdIpMacAddDelThenSuccess(); + customizer.deleteCurrentAttributes(id, entry, writeContext); + verifyBdIpMacAddDelWasInvoked(generateBdIpMacAddDelRequest(ipAddressRaw, physAddressRaw, (byte) 0)); + } + + @Test + public void testDeleteFailed() throws Exception { + whenBdIpMacAddDelThenFailure(); + try { + customizer.deleteCurrentAttributes(id, entry, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyBdIpMacAddDelWasInvoked(generateBdIpMacAddDelRequest(ipAddressRaw, physAddressRaw, (byte) 0)); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizerTest.java new file mode 100644 index 000000000..cab5d5c3b --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizerTest.java @@ -0,0 +1,276 @@ +/* + * 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.vpp; + +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDel; +import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDelReply; +import javax.annotation.Nullable; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +public class BridgeDomainCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { + + private static final String BD_CTX_NAME = "bd-test-instance"; + private static final byte ADD_OR_UPDATE_BD = (byte) 1; + private BridgeDomainCustomizer customizer; + + @Override + public void setUp() throws Exception { + customizer = new BridgeDomainCustomizer(api, new NamingContext("generatedBDName", BD_CTX_NAME)); + } + + @Nullable + private static Boolean intToBoolean(final int value) { + if (value == 0) { + return Boolean.FALSE; + } + if (value == 1) { + return Boolean.TRUE; + } + return null; + } + + private static KeyedInstanceIdentifier bdIdentifierForName( + final String bdName) { + return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(bdName)); + } + + private BridgeDomain generateBridgeDomain(final String bdName) { + final byte arpTerm = 0; + final byte flood = 1; + final byte forward = 0; + final byte learn = 1; + final byte uuf = 0; + return generateBridgeDomain(bdName, arpTerm, flood, forward, learn, uuf); + } + + private BridgeDomain generateBridgeDomain(final String bdName, final int arpTerm, final int flood, + final int forward, final int learn, final int uuf) { + return new BridgeDomainBuilder() + .setName(bdName) + .setArpTermination(intToBoolean(arpTerm)) + .setFlood(intToBoolean(flood)) + .setForward(intToBoolean(forward)) + .setLearn(intToBoolean(learn)) + .setUnknownUnicastFlood(intToBoolean(uuf)) + .build(); + } + + private void verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd, final int bdId) + throws VppInvocationException { + final BridgeDomainAddDel expected = new BridgeDomainAddDel(); + expected.arpTerm = booleanToByte(bd.isArpTermination()); + expected.flood = booleanToByte(bd.isFlood()); + expected.forward = booleanToByte(bd.isForward()); + expected.learn = booleanToByte(bd.isLearn()); + expected.uuFlood = booleanToByte(bd.isUnknownUnicastFlood()); + expected.isAdd = ADD_OR_UPDATE_BD; + expected.bdId = bdId; + verify(api).bridgeDomainAddDel(expected); + } + + private void verifyBridgeDomainDeleteWasInvoked(final int bdId) throws VppInvocationException { + final BridgeDomainAddDel expected = new BridgeDomainAddDel(); + expected.bdId = bdId; + verify(api).bridgeDomainAddDel(expected); + } + + private void whenBridgeDomainAddDelThenSuccess() { + when(api.bridgeDomainAddDel(any(BridgeDomainAddDel.class))).thenReturn(future(new BridgeDomainAddDelReply())); + } + + private void whenBridgeDomainAddDelThenFailure() { + doReturn(failedFuture()).when(api).bridgeDomainAddDel(any(BridgeDomainAddDel.class)); + } + + @Test + public void testAddBridgeDomain() throws Exception { + final int bdId = 1; + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain(bdName); + noMappingDefined(mappingContext, bdName, BD_CTX_NAME); + + whenBridgeDomainAddDelThenSuccess(); + + customizer.writeCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); + + verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId); + verify(mappingContext).put(mappingIid(bdName, BD_CTX_NAME), mapping(bdName, bdId).get()); + } + + @Test + public void testAddBridgeDomainPresentInBdContext() throws Exception { + final int bdId = 1; + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain(bdName); + defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); + + whenBridgeDomainAddDelThenSuccess(); + + customizer.writeCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); + + verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId); + verify(mappingContext).put(mappingIid(bdName, BD_CTX_NAME), mapping(bdName, bdId).get()); + } + + @Test + public void testAddBridgeDomainFailed() throws Exception { + final int bdId = 1; + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain(bdName); + noMappingDefined(mappingContext, bdName, BD_CTX_NAME); + + whenBridgeDomainAddDelThenFailure(); + + try { + customizer.writeCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); + } catch (WriteFailedException e) { + verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testDeleteBridgeDomain() throws Exception { + final int bdId = 1; + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain(bdName); + defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); + + whenBridgeDomainAddDelThenSuccess(); + + customizer.deleteCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); + + verifyBridgeDomainDeleteWasInvoked(bdId); + } + + @Test + public void testDeleteUnknownBridgeDomain() throws Exception { + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain("bd1"); + noMappingDefined(mappingContext, bdName, BD_CTX_NAME); + + try { + customizer.deleteCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); + } catch (IllegalArgumentException e) { + verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class)); + return; + } + fail("IllegalArgumentException was expected"); + } + + @Test + public void testDeleteBridgeDomainFailed() throws Exception { + final int bdId = 1; + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain(bdName); + defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); + + whenBridgeDomainAddDelThenFailure(); + + try { + customizer.deleteCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); + } catch (WriteFailedException e) { + verifyBridgeDomainDeleteWasInvoked(bdId); + return; + } + + fail("WriteFailedException.DeleteFailedException was expected"); + } + + @Test + public void testUpdateBridgeDomain() throws Exception { + final int bdId = 1; + final String bdName = "bd1"; + defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); + + final byte arpTermBefore = 1; + final byte floodBefore = 1; + final byte forwardBefore = 0; + final byte learnBefore = 1; + final byte uufBefore = 0; + + final BridgeDomain dataBefore = + generateBridgeDomain(bdName, arpTermBefore, floodBefore, forwardBefore, learnBefore, uufBefore); + final BridgeDomain dataAfter = + generateBridgeDomain(bdName, arpTermBefore ^ 1, floodBefore ^ 1, forwardBefore ^ 1, learnBefore ^ 1, + uufBefore ^ 1); + + whenBridgeDomainAddDelThenSuccess(); + + customizer + .updateCurrentAttributes(bdIdentifierForName(bdName), dataBefore, dataAfter, + writeContext); + verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter, bdId); + } + + @Test + public void testUpdateUnknownBridgeDomain() throws Exception { + final String bdName = "bd1"; + final BridgeDomain bdBefore = generateBridgeDomain(bdName, 0, 1, 0, 1, 0); + final BridgeDomain bdAfter = generateBridgeDomain(bdName, 1, 1, 0, 1, 0); + noMappingDefined(mappingContext, bdName, BD_CTX_NAME); + + try { + customizer + .updateCurrentAttributes(bdIdentifierForName(bdName), bdBefore, bdAfter, + writeContext); + } catch (IllegalArgumentException e) { + verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class)); + return; + } + fail("IllegalArgumentException was expected"); + } + + @Test + public void testUpdateBridgeDomainFailed() throws Exception { + final int bdId = 1; + final String bdName = "bd1"; + final BridgeDomain bdBefore = generateBridgeDomain(bdName, 0, 1, 0, 1, 0); + final BridgeDomain bdAfter = generateBridgeDomain(bdName, 1, 1, 0, 1, 0); + defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); + + whenBridgeDomainAddDelThenFailure(); + + try { + customizer.updateCurrentAttributes(bdIdentifierForName(bdName), bdBefore, bdAfter, writeContext); + } catch (WriteFailedException e) { + verifyBridgeDomainAddOrUpdateWasInvoked(bdAfter, bdId); + return; + } + fail("IllegalStateException was expected"); + } + +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizerTest.java new file mode 100644 index 000000000..6bb5bc6cf --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizerTest.java @@ -0,0 +1,190 @@ +/* + * 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.vpp; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.L2FibAddDel; +import io.fd.vpp.jvpp.core.dto.L2FibAddDelReply; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class L2FibEntryCustomizerTest extends WriterCustomizerTest { + private static final String BD_CTX_NAME = "bd-test-instance"; + private static final String IFC_CTX_NAME = "ifc-test-instance"; + + private static final String BD_NAME = "testBD0"; + private static final int BD_ID = 111; + private static final String IFACE_NAME = "eth0"; + private static final int IFACE_ID = 123; + + private L2FibEntryCustomizer customizer; + + @Override + public void setUp() throws Exception { + defineMapping(mappingContext, BD_NAME, BD_ID, BD_CTX_NAME); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + + customizer = new L2FibEntryCustomizer( + api, + new NamingContext("generatedBdName", BD_CTX_NAME), + new NamingContext("generatedIfaceName", IFC_CTX_NAME)); + } + + private static InstanceIdentifier getL2FibEntryId(final PhysAddress address) { + return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(BD_NAME)) + .child(L2FibTable.class).child(L2FibEntry.class, new L2FibEntryKey(address)); + } + + private void whenL2FibAddDelThenSuccess() { + doReturn(future(new L2FibAddDelReply())).when(api).l2FibAddDel(any(L2FibAddDel.class)); + } + + private void whenL2FibAddDelThenFailure() { + doReturn(failedFuture()).when(api).l2FibAddDel(any(L2FibAddDel.class)); + } + + private L2FibAddDel generateL2FibAddDelRequest(final long mac, final byte isAdd) { + final L2FibAddDel request = new L2FibAddDel(); + request.mac = mac; + request.bdId = BD_ID; + request.swIfIndex = IFACE_ID; + request.isAdd = isAdd; + if (isAdd == 1) { + request.staticMac = 1; + request.filterMac = 1; + } + return request; + } + + private L2FibEntry generateL2FibEntry(final PhysAddress address) { + final L2FibEntryBuilder entry = new L2FibEntryBuilder(); + entry.setKey(new L2FibEntryKey(address)); + entry.setPhysAddress(address); + entry.setStaticConfig(true); + entry.setBridgedVirtualInterface(false); + entry.setAction(L2FibFilter.class); + entry.setOutgoingInterface(IFACE_NAME); + return entry.build(); + } + + private void verifyL2FibAddDelWasInvoked(final L2FibAddDel expected) throws + VppInvocationException { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(L2FibAddDel.class); + verify(api).l2FibAddDel(argumentCaptor.capture()); + final L2FibAddDel actual = argumentCaptor.getValue(); + assertEquals(expected.mac, actual.mac); + assertEquals(expected.bdId, actual.bdId); + assertEquals(expected.swIfIndex, actual.swIfIndex); + assertEquals(expected.isAdd, actual.isAdd); + assertEquals(expected.staticMac, actual.staticMac); + assertEquals(expected.filterMac, actual.filterMac); + } + + @Test + public void testCreate() throws Exception { + final long address_vpp = 0x0102030405060000L; + final PhysAddress address = new PhysAddress("01:02:03:04:05:06"); + final L2FibEntry entry = generateL2FibEntry(address); + final InstanceIdentifier id = getL2FibEntryId(address); + + whenL2FibAddDelThenSuccess(); + + customizer.writeCurrentAttributes(id, entry, writeContext); + + verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 1)); + } + + @Test + public void testCreateFailed() throws Exception { + final long address_vpp = 0x1122334455660000L; + final PhysAddress address = new PhysAddress("11:22:33:44:55:66"); + final L2FibEntry entry = generateL2FibEntry(address); + final InstanceIdentifier id = getL2FibEntryId(address); + + whenL2FibAddDelThenFailure(); + + try { + customizer.writeCurrentAttributes(id, entry, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 1)); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdate() throws Exception { + customizer.updateCurrentAttributes(InstanceIdentifier.create(L2FibEntry.class), mock(L2FibEntry.class), + mock(L2FibEntry.class), writeContext); + } + + @Test + public void testDelete() throws Exception { + final long address_vpp = 0x1122334455660000L; + final PhysAddress address = new PhysAddress("11:22:33:44:55:66"); + final L2FibEntry entry = generateL2FibEntry(address); + final InstanceIdentifier id = getL2FibEntryId(address); + + whenL2FibAddDelThenSuccess(); + + customizer.deleteCurrentAttributes(id, entry, writeContext); + + verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 0)); + } + + @Test + public void testDeleteFailed() throws Exception { + final long address_vpp = 0x0102030405060000L; + final PhysAddress address = new PhysAddress("01:02:03:04:05:06"); + final L2FibEntry entry = generateL2FibEntry(address); + final InstanceIdentifier id = getL2FibEntryId(address); + + whenL2FibAddDelThenFailure(); + + try { + customizer.deleteCurrentAttributes(id, entry, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 0)); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReaderTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReaderTest.java new file mode 100644 index 000000000..f8645da4d --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionReaderTest.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.vppclassifier; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDetails; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.ClassifySessionDump; + +public class ClassifySessionReaderTest extends + ListReaderCustomizerTest { + + private static final String MATCH_1 = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + private static final String MATCH_2 = "00:00:00:00:00:00:01:02:03:04:05:07:00:00:00:00"; + + private static final int TABLE_INDEX = 1; + private static final String TABLE_NAME = "table1"; + + @Mock + private VppClassifierContextManager classifierContext; + + public ClassifySessionReaderTest() { + super(ClassifySession.class, ClassifyTableBuilder.class); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new ClassifySessionReader(api, classifierContext); + } + + private static InstanceIdentifier getClassifySessionId(final String tableName, + final String match) { + return InstanceIdentifier.create(VppClassifierState.class) + .child(ClassifyTable.class, new ClassifyTableKey(tableName)) + .child(ClassifySession.class, new ClassifySessionKey(new HexString(match))); + } + + @Test + public void testReadWithCache() throws ReadFailedException { + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, MATCH_1); + final ClassifySessionBuilder builder = mock(ClassifySessionBuilder.class); + final ModificationCache cache = new ModificationCache(); + final ClassifySessionDetailsReplyDump dump = new ClassifySessionDetailsReplyDump(); + final ClassifySessionDetails details = new ClassifySessionDetails(); + details.match = + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + dump.classifySessionDetails = Collections.singletonList(details); + cache.put(ClassifySessionReader.CACHE_KEY + id.firstKeyOf(ClassifyTable.class), dump); + when(ctx.getModificationCache()).thenReturn(cache); + + getCustomizer().readCurrentAttributes(id, builder, ctx); + } + + @Test + public void testGetAllIds() throws ReadFailedException { + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, MATCH_1); + final ClassifySessionDetailsReplyDump dump = new ClassifySessionDetailsReplyDump(); + final ClassifySessionDetails details1 = new ClassifySessionDetails(); + details1.match = + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + final ClassifySessionDetails details2 = new ClassifySessionDetails(); + details2.match = + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x07, 0x00, 0x00, 0x00, 0x00}; + dump.classifySessionDetails = Arrays.asList(details1, details2); + doReturn(future(dump)).when(api).classifySessionDump(any(ClassifySessionDump.class)); + + when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); + when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + + final List allIds = getCustomizer().getAllIds(id, ctx); + assertEquals(2, allIds.size()); + assertEquals(MATCH_1, allIds.get(0).getMatch().getValue()); + assertEquals(MATCH_2, allIds.get(1).getMatch().getValue()); + } + +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriterTest.java new file mode 100644 index 000000000..654900c81 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifySessionWriterTest.java @@ -0,0 +1,179 @@ +/* + * 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.vppclassifier; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class ClassifySessionWriterTest extends WriterCustomizerTest { + + private static final int TABLE_INDEX = 123; + private static final String TABLE_NAME = "table123"; + + @Mock + private VppClassifierContextManager classfierContext; + + private ClassifySessionWriter customizer; + private static final int SESSION_INDEX = 456; + + @Override + public void setUp() throws Exception { + customizer = new ClassifySessionWriter(api, classfierContext); + + when(classfierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); + when(classfierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + + final ClassifyTable table = mock(ClassifyTable.class); + when(table.getClassifierNode()).thenReturn(new VppNodeName("ip4-classifier")); + when(writeContext.readAfter(any())).thenReturn(Optional.of(table)); + when(writeContext.readBefore(any())).thenReturn(Optional.of(table)); + } + + private static ClassifySession generateClassifySession(final long opaqueIndex, final String match) { + final ClassifySessionBuilder builder = new ClassifySessionBuilder(); + builder.setOpaqueIndex(new OpaqueIndex(opaqueIndex)); + builder.setHitNext(new VppNode(PacketHandlingAction.Deny)); + builder.setAdvance(123); + builder.setMatch(new HexString(match)); + return builder.build(); + } + + private static InstanceIdentifier getClassifySessionId(final String tableName, + final String match) { + return InstanceIdentifier.create(VppClassifier.class) + .child(ClassifyTable.class, new ClassifyTableKey(tableName)) + .child(ClassifySession.class, new ClassifySessionKey(new HexString(match))); + } + + private void whenClassifyAddDelSessionThenSuccess() { + doReturn(future(new ClassifyAddDelSessionReply())).when(api) + .classifyAddDelSession(any(ClassifyAddDelSession.class)); + } + + private void whenClassifyAddDelSessionThenFailure() { + doReturn(failedFuture()).when(api).classifyAddDelSession(any(ClassifyAddDelSession.class)); + } + + private static ClassifyAddDelSession generateClassifyAddDelSession(final byte isAdd, final int tableIndex, + final int sessionIndex) { + final ClassifyAddDelSession request = new ClassifyAddDelSession(); + request.isAdd = isAdd; + request.tableIndex = tableIndex; + request.opaqueIndex = sessionIndex; + request.hitNextIndex = 0; + request.advance = 123; + request.match = + new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + return request; + } + + @Test + public void testCreate() throws Exception { + final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); + + whenClassifyAddDelSessionThenSuccess(); + + customizer.writeCurrentAttributes(id, classifySession, writeContext); + + verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX)); + } + + @Test + public void testCreateFailed() throws Exception { + final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); + + whenClassifyAddDelSessionThenFailure(); + + try { + customizer.writeCurrentAttributes(id, classifySession, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX)); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdate() throws Exception { + customizer.updateCurrentAttributes(null, null, null, writeContext); + } + + @Test + public void testDelete() throws Exception { + final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); + + whenClassifyAddDelSessionThenSuccess(); + + customizer.deleteCurrentAttributes(id, classifySession, writeContext); + + verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX)); + } + + @Test + public void testDeleteFailed() throws Exception { + final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); + final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); + + whenClassifyAddDelSessionThenFailure(); + + try { + customizer.deleteCurrentAttributes(id, classifySession, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX)); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + + customizer.deleteCurrentAttributes(id, classifySession, writeContext); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReaderTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReaderTest.java new file mode 100644 index 000000000..70200743f --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableReaderTest.java @@ -0,0 +1,126 @@ +/* + * 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.vppclassifier; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import java.util.List; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.ClassifyTableIds; +import io.fd.vpp.jvpp.core.dto.ClassifyTableIdsReply; +import io.fd.vpp.jvpp.core.dto.ClassifyTableInfo; +import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply; + +public class ClassifyTableReaderTest extends + ListReaderCustomizerTest { + + private static final int TABLE_INDEX_1 = 1; + private static final String TABLE_NAME_1 = "table1"; + private static final int TABLE_INDEX_2 = 2; + private static final String TABLE_NAME_2 = "table2"; + + @Mock + private VppClassifierContextManager classifierContext; + + public ClassifyTableReaderTest() { + super(ClassifyTable.class, VppClassifierStateBuilder.class); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new ClassifyTableReader(api, classifierContext); + } + + private static InstanceIdentifier getClassifyTableId(final String name) { + return InstanceIdentifier.create(VppClassifierState.class) + .child(ClassifyTable.class, new ClassifyTableKey(name)); + } + + private static ClassifyTableInfoReply generateClassifyTableInfoReply() { + final ClassifyTableInfoReply reply = new ClassifyTableInfoReply(); + reply.tableId = TABLE_INDEX_1; + reply.nbuckets = 2; + reply.skipNVectors = 0; + reply.matchNVectors = 1; + reply.nextTableIndex = ~0; + reply.missNextIndex = ~0; + reply.mask = + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + return reply; + } + + private void verifyClasifyTableRead(final ClassifyTableBuilder builder) { + verify(builder).setName(TABLE_NAME_1); + verify(builder).setNbuckets(2L); + verify(builder, times(0)).setNextTable(anyString()); + verify(builder).setMissNext(new VppNode(PacketHandlingAction.Permit)); + verify(builder).setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00")); + verify(builder).setActiveSessions(0L); + } + + @Test + public void testRead() throws ReadFailedException { + doReturn(future(generateClassifyTableInfoReply())).when(api).classifyTableInfo(any(ClassifyTableInfo.class)); + + when(classifierContext.containsTable(TABLE_NAME_1, mappingContext)).thenReturn(true); + when(classifierContext.getTableIndex(TABLE_NAME_1, mappingContext)).thenReturn(TABLE_INDEX_1); + when(classifierContext.getTableBaseNode(TABLE_NAME_1, mappingContext)).thenReturn(Optional.absent()); + + final ClassifyTableBuilder builder = mock(ClassifyTableBuilder.class); + getCustomizer().readCurrentAttributes(getClassifyTableId(TABLE_NAME_1), builder, ctx); + + verifyClasifyTableRead(builder); + } + + @Test + public void testGetAllIds() throws ReadFailedException { + final ClassifyTableIdsReply reply = new ClassifyTableIdsReply(); + reply.ids = new int[] {1, 2}; + doReturn(future(reply)).when(api).classifyTableIds(any(ClassifyTableIds.class)); + + when(classifierContext.getTableName(TABLE_INDEX_1, mappingContext)).thenReturn(TABLE_NAME_1); + when(classifierContext.getTableName(TABLE_INDEX_2, mappingContext)).thenReturn(TABLE_NAME_2); + + final List allIds = getCustomizer().getAllIds(getClassifyTableId(TABLE_NAME_1), ctx); + + assertEquals(reply.ids.length, allIds.size()); + assertEquals(TABLE_NAME_1, allIds.get(0).getName()); + assertEquals(TABLE_NAME_2, allIds.get(1).getName()); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriterTest.java new file mode 100644 index 000000000..a4da54631 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/ClassifyTableWriterTest.java @@ -0,0 +1,181 @@ +/* + * 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.vppclassifier; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class ClassifyTableWriterTest extends WriterCustomizerTest { + + private static final int TABLE_INDEX = 123; + private static final String TABLE_NAME = "table123"; + + @Mock + private VppClassifierContextManager classifierContext; + + private ClassifyTableWriter customizer; + + @Override + public void setUp() throws Exception { + customizer = new ClassifyTableWriter(api, classifierContext); + } + + private static ClassifyTable generateClassifyTable(final String name) { + final ClassifyTableBuilder builder = new ClassifyTableBuilder(); + builder.setName(name); + builder.setClassifierNode(new VppNodeName("ip4-classifier")); + builder.setKey(new ClassifyTableKey(name)); + builder.setSkipNVectors(0L); + builder.setNbuckets(2L); + builder.setMemorySize(2L << 20); + builder.setMissNext(new VppNode(PacketHandlingAction.Permit)); + builder.setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00")); + return builder.build(); + } + + private static InstanceIdentifier getClassifyTableId(final String name) { + return InstanceIdentifier.create(VppClassifier.class) + .child(ClassifyTable.class, new ClassifyTableKey(name)); + } + + private void whenClassifyAddDelTableThenSuccess() { + final ClassifyAddDelTableReply reply = new ClassifyAddDelTableReply(); + reply.newTableIndex = TABLE_INDEX; + doReturn(future(reply)).when(api).classifyAddDelTable(any(ClassifyAddDelTable.class)); + } + + private void whenClassifyAddDelTableThenFailure() { + doReturn(failedFuture()).when(api).classifyAddDelTable(any(ClassifyAddDelTable.class)); + } + + private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd) { + return generateClassifyAddDelTable(isAdd, -1); + } + + private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd, final int tableIndex) { + final ClassifyAddDelTable request = new ClassifyAddDelTable(); + request.isAdd = isAdd; + request.tableIndex = tableIndex; + request.nbuckets = 2; + request.memorySize = 2 << 20; + request.skipNVectors = 0; + request.matchNVectors = 1; + request.nextTableIndex = ~0; + request.missNextIndex = ~0; + request.mask = + new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + return request; + } + + @Test + public void testCreate() throws Exception { + final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + + whenClassifyAddDelTableThenSuccess(); + + customizer.writeCurrentAttributes(id, classifyTable, writeContext); + + verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 1)); + verify(classifierContext) + .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext); + } + + @Test + public void testCreateFailed() throws Exception { + final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + + whenClassifyAddDelTableThenFailure(); + + try { + customizer.writeCurrentAttributes(id, classifyTable, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 1)); + verify(classifierContext, times(0)) + .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext); + return; + } + fail("WriteFailedException.CreateFailedException was expected"); + } + + @Test + public void testDelete() throws Exception { + final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + + when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); + when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + whenClassifyAddDelTableThenSuccess(); + + customizer.deleteCurrentAttributes(id, classifyTable, writeContext); + + verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 0, TABLE_INDEX)); + } + + @Test + public void testDeleteFailed() throws Exception { + final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + + when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); + when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); + whenClassifyAddDelTableThenFailure(); + + try { + customizer.deleteCurrentAttributes(id, classifyTable, writeContext); + } catch (WriteFailedException e) { + assertTrue(e.getCause() instanceof VppBaseCallException); + verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 0, TABLE_INDEX)); + return; + } + fail("WriteFailedException.DeleteFailedException was expected"); + + customizer.deleteCurrentAttributes(id, classifyTable, writeContext); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdate() throws Exception { + final ClassifyTable classifyTableBefore = generateClassifyTable(TABLE_NAME); + final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); + customizer.updateCurrentAttributes(id, classifyTableBefore, new ClassifyTableBuilder().build(), writeContext); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImplTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImplTest.java new file mode 100644 index 000000000..c334fe84f --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppclassifier/VppClassifierContextManagerImplTest.java @@ -0,0 +1,163 @@ +/* + * 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.vppclassifier; + +import static io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManagerImpl.VPP_CLASSIFIER_CONTEXT_IID; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import java.util.Arrays; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextKey; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +public class VppClassifierContextManagerImplTest { + + private static final int TABLE_ID_0 = 0; + private static final String TABLE_NAME_0 = "table0"; + private static final KeyedInstanceIdentifier TABLE_IID_0 = + VPP_CLASSIFIER_CONTEXT_IID.child(ClassifyTableContext.class, new ClassifyTableContextKey(TABLE_NAME_0)); + + private static final int TABLE_ID_1 = 1; + private static final String TABLE_NAME_1 = "table1"; + + private VppClassifierContextManagerImpl vppClassfierContext; + + @Mock + private MappingContext ctx; + + @Before + public void setUp() throws Exception { + initMocks(this); + vppClassfierContext = new VppClassifierContextManagerImpl("classify-table-"); + } + + @Test + public void testAddTable() throws Exception { + final String classfierNodeName = "node123"; + vppClassfierContext.addTable(TABLE_ID_0, TABLE_NAME_0, new VppNodeName(classfierNodeName), ctx); + verify(ctx).put(TABLE_IID_0, table(TABLE_ID_0, TABLE_NAME_0, classfierNodeName)); + } + + @Test + public void testContainsTable() throws Exception { + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.absent()); + assertFalse(vppClassfierContext.containsTable(TABLE_NAME_0, ctx)); + } + + @Test + public void testGetTableIndex() throws Exception { + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(table(TABLE_ID_0, TABLE_NAME_0))); + assertEquals(TABLE_ID_0, vppClassfierContext.getTableIndex(TABLE_NAME_0, ctx)); + } + + @Test + public void testGetTableName() throws Exception { + when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)) + .thenReturn(Optional.of(context(table(TABLE_ID_0, TABLE_NAME_0), table(TABLE_ID_1, TABLE_NAME_1)))); + assertEquals(TABLE_NAME_0, (vppClassfierContext.getTableName(TABLE_ID_0, ctx))); + } + + @Test + public void testGetTableBaseNode() throws Exception { + final String classfierNodeName = "node123"; + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(table(TABLE_ID_0, TABLE_NAME_0, classfierNodeName))); + vppClassfierContext.getTableBaseNode(TABLE_NAME_0, ctx); + assertEquals(Optional.of(classfierNodeName), (vppClassfierContext.getTableBaseNode(TABLE_NAME_0, ctx))); + } + + @Test + public void testRemoveTable() throws Exception { + vppClassfierContext.removeTable(TABLE_NAME_0, ctx); + verify(ctx).delete(TABLE_IID_0); + } + + @Test + public void testAddNodeName() throws Exception { + final String nodeName = "node123"; + final int nodeIndex = 1; + + vppClassfierContext.addNodeName(TABLE_NAME_0, nodeIndex, nodeName, ctx); + verify(ctx).put( + TABLE_IID_0.child(NodeContext.class, new NodeContextKey(nodeName)), + node(nodeName, nodeIndex) + ); + } + + @Test + public void testGetNonExistingNodeName() throws Exception { + when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(table(TABLE_ID_1, TABLE_NAME_1)))); + assertFalse(vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx).isPresent()); + } + + @Test + public void testGetNodeNameMissingNodeCtx() throws Exception { + final ClassifyTableContext tableCtx = table(TABLE_ID_0, TABLE_NAME_0, "aa"); + when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(tableCtx))); + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(tableCtx)); + assertEquals(Optional.absent(), vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx)); + } + + @Test + public void testGetNodeName() throws Exception { + final ClassifyTableContext tableCtx = table(TABLE_ID_0, TABLE_NAME_0, "aa", node("node123", 123)); + when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(tableCtx))); + when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(tableCtx)); + assertEquals(Optional.of("node123"), vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx)); + } + + private VppClassifierContext context(ClassifyTableContext... tables) { + VppClassifierContextBuilder context = new VppClassifierContextBuilder(); + context.setClassifyTableContext(Arrays.asList(tables)); + return context.build(); + } + + private static ClassifyTableContext table(final Integer id, final String name) { + return table(id, name, null); + } + + private static ClassifyTableContext table(final Integer id, final String name, final String classfierNodeName, + final NodeContext... nodeContexts) { + final ClassifyTableContextBuilder builder = + new ClassifyTableContextBuilder().setIndex(id).setName(name).setClassifierNodeName(classfierNodeName); + + if (nodeContexts.length > 0) { + builder.setNodeContext(Arrays.asList(nodeContexts)); + } + + return builder.build(); + } + + private NodeContext node(final String nodeName, final int nodeIndex) { + return new NodeContextBuilder().setName(nodeName).setIndex(nodeIndex).build(); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizerTest.java new file mode 100644 index 000000000..0fbdb986e --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizerTest.java @@ -0,0 +1,47 @@ +/* + * 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.vppstate; + +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; + +public class BridgeDomainCustomizerTest + extends ListReaderCustomizerTest { + + private NamingContext bdContext; + private NamingContext interfacesContext; + + public BridgeDomainCustomizerTest() { + super(BridgeDomain.class, BridgeDomainsBuilder.class); + } + + @Override + public void setUp() { + bdContext = new NamingContext("generatedBdName", "bd-test-instance"); + interfacesContext = new NamingContext("generatedIfaceName", "ifc-test-instance"); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new BridgeDomainCustomizer(api, bdContext); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizerTest.java new file mode 100644 index 000000000..94a654c15 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizerTest.java @@ -0,0 +1,124 @@ +/* + * 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.vppstate; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibForward; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppInvocationException; +import io.fd.vpp.jvpp.core.dto.L2FibTableDump; +import io.fd.vpp.jvpp.core.dto.L2FibTableEntry; +import io.fd.vpp.jvpp.core.dto.L2FibTableEntryReplyDump; + +public class L2FibEntryCustomizerTest extends ListReaderCustomizerTest { + + private static final String BD_NAME = "testBD0"; + private static final int BD_ID = 111; + private static final String IFACE_NAME = "eth0"; + private static final int IFACE_ID = 123; + private static final String BD_CTX_NAME = "bd-test-instance"; + private static final String IFC_CTX_NAME = "ifc-test-instance"; + private NamingContext bdContext; + private NamingContext interfacesContext; + + public L2FibEntryCustomizerTest() { + super(L2FibEntry.class, L2FibTableBuilder.class); + } + + @Override + public void setUp() { + bdContext = new NamingContext("generatedBdName", BD_CTX_NAME); + defineMapping(mappingContext, BD_NAME, BD_ID, BD_CTX_NAME); + interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new L2FibEntryCustomizer(api, bdContext, interfacesContext); + } + + private static InstanceIdentifier getL2FibEntryId(final String bdName, final PhysAddress address) { + return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(bdName)) + .child(L2FibTable.class).child(L2FibEntry.class, new L2FibEntryKey(address)); + } + + private void whenL2FibTableDumpThenReturn(final List l2FibTableEntryList) + throws ExecutionException, InterruptedException, VppInvocationException { + final L2FibTableEntryReplyDump reply = new L2FibTableEntryReplyDump(); + reply.l2FibTableEntry = l2FibTableEntryList; + when(api.l2FibTableDump(any(L2FibTableDump.class))).thenReturn(future(reply)); + } + + @Test + public void testRead() throws Exception { + final long address_vpp = 0x0000010203040506L; + final PhysAddress address = new PhysAddress("01:02:03:04:05:06"); + defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); + + whenL2FibTableDumpThenReturn(Collections.singletonList(generateL2FibEntry(address_vpp))); + + final L2FibEntryBuilder builder = mock(L2FibEntryBuilder.class); + getCustomizer().readCurrentAttributes(getL2FibEntryId(BD_NAME, address), builder, ctx); + + verify(builder).setAction(L2FibForward.class); + verify(builder).setBridgedVirtualInterface(false); + verify(builder).setOutgoingInterface(IFACE_NAME); + verify(builder).setStaticConfig(false); + verify(builder).setPhysAddress(address); + verify(builder).setKey(new L2FibEntryKey(address)); + } + + private L2FibTableEntry generateL2FibEntry(final long mac) { + final L2FibTableEntry entry = new L2FibTableEntry(); + entry.mac = mac; + entry.swIfIndex = IFACE_ID; + return entry; + } + + @Test + public void testGetAllIds() throws Exception { + final long address_vpp = 0x0000112233445566L; + final PhysAddress address = new PhysAddress("11:22:33:44:55:66"); + + whenL2FibTableDumpThenReturn(Collections.singletonList(generateL2FibEntry(address_vpp))); + + final List ids = getCustomizer().getAllIds(getL2FibEntryId(BD_NAME, address), ctx); + assertEquals(1, ids.size()); + assertEquals(address, ids.get(0).getPhysAddress()); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizerTest.java new file mode 100644 index 000000000..2f12cbde1 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizerTest.java @@ -0,0 +1,60 @@ +/* + * 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.vppstate; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.hc2vpp.common.test.read.ReaderCustomizerTest; +import io.fd.vpp.jvpp.core.dto.ShowVersion; +import io.fd.vpp.jvpp.core.dto.ShowVersionReply; +import io.fd.vpp.jvpp.dto.ControlPing; +import io.fd.vpp.jvpp.dto.ControlPingReply; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.VersionBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class VersionCustomizerTest extends ReaderCustomizerTest { + + public VersionCustomizerTest() { + super(Version.class, VppStateBuilder.class); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new VersionCustomizer(api); + } + + @Test + public void testReadCurrentAttributes() throws Exception { + final ShowVersionReply reply = new ShowVersionReply(); + reply.version = new byte[] {}; + reply.program = new byte[] {}; + reply.buildDate = new byte[] {}; + reply.buildDirectory = new byte[] {}; + + when(api.showVersion(any(ShowVersion.class))).thenReturn(future(reply)); + when(api.send(any(ControlPing.class))).thenReturn(future(new ControlPingReply())); + getCustomizer().readCurrentAttributes(InstanceIdentifier.create(Version.class), new VersionBuilder(), ctx); + verify(api).showVersion(any(ShowVersion.class)); + verify(api).send(any(ControlPing.class)); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/VppStateTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/VppStateTest.java new file mode 100644 index 000000000..7134a595a --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vppstate/VppStateTest.java @@ -0,0 +1,326 @@ +/* + * 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.vppstate; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.common.base.Optional; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.impl.read.GenericReader; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.read.registry.ReaderRegistry; +import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; +import io.fd.hc2vpp.common.test.util.NamingContextHelper; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.test.util.FutureProducer; +import io.fd.vpp.jvpp.dto.ControlPing; +import io.fd.vpp.jvpp.dto.ControlPingReply; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nonnull; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.VersionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; +import io.fd.vpp.jvpp.core.dto.L2FibTableDump; +import io.fd.vpp.jvpp.core.dto.L2FibTableEntry; +import io.fd.vpp.jvpp.core.dto.L2FibTableEntryReplyDump; +import io.fd.vpp.jvpp.core.dto.ShowVersion; +import io.fd.vpp.jvpp.core.dto.ShowVersionReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +public class VppStateTest implements FutureProducer, NamingContextHelper { + + private static final String BD_CTX_NAME = "bd-test-instance"; + @Mock + private FutureJVppCore api; + @Mock + private ReadContext ctx; + @Mock + private MappingContext mappingContext; + + private NamingContext bdContext; + + private ReaderRegistry readerRegistry; + + private static InstanceIdentifier bridgeDomainsId; + + /** + * Create root VppState reader with all its children wired. + */ + private static ReaderRegistry getVppStateReader(@Nonnull final FutureJVppCore jVpp, + @Nonnull final NamingContext bdContext) { + final CompositeReaderRegistryBuilder registry = new CompositeReaderRegistryBuilder(); + + // VppState(Structural) + final InstanceIdentifier vppStateId = InstanceIdentifier.create(VppState.class); + registry.addStructuralReader(vppStateId, VppStateBuilder.class); + // Version + registry.add(new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp))); + // BridgeDomains(Structural) + bridgeDomainsId = vppStateId.child(BridgeDomains.class); + registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class); + // BridgeDomain + registry.add(getBridgeDomainReader(jVpp, bdContext)); + return registry.build(); + } + + private static GenericListReader getBridgeDomainReader( + final @Nonnull FutureJVppCore jVpp, final @Nonnull NamingContext bdContext) { + final InstanceIdentifier bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class); + return new GenericListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdContext)); + } + + @Before + public void setUp() throws Exception { + initMocks(this); + final ModificationCache cache = new ModificationCache(); + doReturn(cache).when(ctx).getModificationCache(); + doReturn(mappingContext).when(ctx).getMappingContext(); + + bdContext = new NamingContext("generatedBdName", BD_CTX_NAME); + readerRegistry = getVppStateReader(api, bdContext); + } + + private static Version getVersion() { + return new VersionBuilder() + .setName("test") + .setBuildDirectory("1") + .setBranch("2") + .setBuildDate("3") + .setPid(0L) + .build(); + } + + private void whenShowVersionThenReturn(final Version version) { + final ShowVersionReply reply = new ShowVersionReply(); + reply.buildDate = version.getBuildDate().getBytes(); + reply.program = version.getName().getBytes(); + reply.version = version.getBranch().getBytes(); + reply.buildDirectory = version.getBuildDirectory().getBytes(); + when(api.showVersion(any(ShowVersion.class))).thenReturn(future(reply)); + // Version Customizer uses ControlPing to obtain PID + when(api.send(any(ControlPing.class))).thenReturn(future(new ControlPingReply())); + } + + private void whenL2FibTableDumpThenReturn(final List entryList) { + final L2FibTableEntryReplyDump reply = new L2FibTableEntryReplyDump(); + reply.l2FibTableEntry = entryList; + when(api.l2FibTableDump(any(L2FibTableDump.class))).thenReturn(future(reply)); + } + + private void whenBridgeDomainDumpThenReturn(final List bdList) { + final BridgeDomainDetailsReplyDump reply = new BridgeDomainDetailsReplyDump(); + reply.bridgeDomainDetails = bdList; + + doAnswer(invocation -> { + BridgeDomainDump request = (BridgeDomainDump) invocation.getArguments()[0]; + if (request.bdId == -1) { + reply.bridgeDomainDetails = bdList; + } else { + reply.bridgeDomainDetails = Collections.singletonList(bdList.get(request.bdId)); + } + return future(reply); + }).when(api).bridgeDomainDump(any(BridgeDomainDump.class)); + } + + @Test + public void testReadAll() throws Exception { + final Version version = getVersion(); + whenShowVersionThenReturn(version); + + final BridgeDomainDetails bridgeDomainDetails = new BridgeDomainDetails(); + final BridgeDomainDetails bridgeDomainDetails2 = new BridgeDomainDetails(); + bridgeDomainDetails2.bdId = 1; + + final List bdList = Arrays.asList(bridgeDomainDetails, bridgeDomainDetails2); + mockBdMapping(bridgeDomainDetails, "bd1"); + mockBdMapping(bridgeDomainDetails2, "bd2"); + + whenBridgeDomainDumpThenReturn(bdList); + + final Multimap, ? extends DataObject> dataObjects = + readerRegistry.readAll(ctx); + assertEquals(dataObjects.size(), 1); + final VppState dataObject = + (VppState) Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet()))); + assertEquals(version, dataObject.getVersion()); + assertEquals(2, dataObject.getBridgeDomains().getBridgeDomain().size()); + } + + @Test + public void testReadSpecific() throws Exception { + final Version version = getVersion(); + whenShowVersionThenReturn(version); + whenBridgeDomainDumpThenReturn(Collections.emptyList()); + + final Optional read = readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx); + assertTrue(read.isPresent()); + assertEquals(version, ((VppState) read.get()).getVersion()); + } + + @Test + public void testReadBridgeDomains() throws Exception { + final Version version = getVersion(); + whenShowVersionThenReturn(version); + final BridgeDomainDetails details = new BridgeDomainDetails(); + whenBridgeDomainDumpThenReturn(Collections.singletonList(details)); + + mockBdMapping(details, "bdn1"); + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); + + Optional read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class), ctx); + assertTrue(read.isPresent()); + assertEquals(readRoot.getBridgeDomains(), read.get()); + } + + /** + * L2fib does not have a dedicated reader, relying on auto filtering + */ + @Test + @Ignore("L2 FIB was moved to dedicated customizer. TODO: add infra test that covers such case") + @SuppressWarnings("unchecked") + public void testReadL2Fib() throws Exception { + final BridgeDomainDetails bd = new BridgeDomainDetails(); + bd.bdId = 0; + final String bdName = "bdn1"; + mockBdMapping(bd, bdName); + defineMapping(mappingContext, "eth1", 0, "ifc-test-instance"); + + whenBridgeDomainDumpThenReturn(Collections.singletonList(bd)); + final L2FibTableEntry l2FibEntry = new L2FibTableEntry(); + l2FibEntry.bdId = 0; + l2FibEntry.mac = 0x0605040302010000L; + whenL2FibTableDumpThenReturn(Collections.singletonList(l2FibEntry)); + + // Deep child without a dedicated reader with specific l2fib key + final InstanceIdentifier idExisting = + InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("bdn1")).child(L2FibTable.class) + .child(L2FibEntry.class, new L2FibEntryKey(new PhysAddress("01:02:03:04:05:06"))); + Optional read = + readerRegistry.read(idExisting, ctx); + assertTrue(read.isPresent()); + + // non existing l2fib + final InstanceIdentifier idNonExisting = + InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("bdn1")).child(L2FibTable.class) + .child(L2FibEntry.class, new L2FibEntryKey(new PhysAddress("FF:FF:FF:04:05:06"))); + read = readerRegistry.read(idNonExisting, ctx); + assertFalse(read.isPresent()); + } + + private void mockBdMapping(final BridgeDomainDetails bd, final String bdName) { + defineMapping(mappingContext, bdName, bd.bdId, BD_CTX_NAME); + } + + @Test + public void testReadBridgeDomainAll() throws Exception { + final Version version = getVersion(); + whenShowVersionThenReturn(version); + final BridgeDomainDetails details = new BridgeDomainDetails(); + whenBridgeDomainDumpThenReturn(Collections.singletonList(details)); + mockBdMapping(details, "bd2"); + + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); + + final GenericListReader bridgeDomainReader = + getBridgeDomainReader(api, bdContext); + + final List read = + bridgeDomainReader.readList(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class), ctx); + + assertEquals(readRoot.getBridgeDomains().getBridgeDomain(), read); + } + + @Test + public void testReadBridgeDomain() throws Exception { + final BridgeDomainDetails bd = new BridgeDomainDetails(); + bd.bdId = 0; + final String bdName = "bdn1"; + mockBdMapping(bd, bdName); + + whenBridgeDomainDumpThenReturn(Collections.singletonList(bd)); + whenShowVersionThenReturn(getVersion()); + + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); + + final Optional read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey(bdName)), ctx); + + assertTrue(read.isPresent()); + assertEquals(readRoot.getBridgeDomains().getBridgeDomain().stream().filter( + input -> input.getKey().getName().equals(bdName)).findFirst().get(), + read.get()); + } + + @Test(expected = ReadFailedException.class) + public void testReadBridgeDomainNotExisting() throws Exception { + final String nonExistingBdName = "NOT EXISTING"; + noMappingDefined(mappingContext, nonExistingBdName, BD_CTX_NAME); + + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey(nonExistingBdName)), ctx); + } + + @Test + public void testReadVersion() throws Exception { + whenShowVersionThenReturn(getVersion()); + whenBridgeDomainDumpThenReturn(Collections.emptyList()); + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); + + Optional read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(Version.class), ctx); + assertTrue(read.isPresent()); + assertEquals(readRoot.getVersion(), read.get()); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/DisabledInterfacesManagerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/DisabledInterfacesManagerTest.java deleted file mode 100644 index 52a7a5c2d..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/DisabledInterfacesManagerTest.java +++ /dev/null @@ -1,109 +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.honeycomb.translate.v3po; - - - - -import static org.hamcrest.CoreMatchers.hasItems; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.DisabledInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.DisabledInterfacesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndex; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndexBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.context.rev160909.disabled.interfaces.DisabledInterfaceIndexKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; - -public class DisabledInterfacesManagerTest { - - private static final InstanceIdentifier - ROOT_ID = InstanceIdentifier.create(DisabledInterfaces.class); - private static final KeyedInstanceIdentifier SPECIFIC_ID_1 = - ROOT_ID.child(DisabledInterfaceIndex.class, new DisabledInterfaceIndexKey(1)); - private static final KeyedInstanceIdentifier SPECIFIC_ID_4 = - ROOT_ID.child(DisabledInterfaceIndex.class, new DisabledInterfaceIndexKey(4)); - - @Mock - private MappingContext mappingContext; - private DisabledInterfacesManager manager; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - manager = new DisabledInterfacesManager(); - doReturn(Optional.of(new DisabledInterfacesBuilder().setDisabledInterfaceIndex(toIndices(1, 2, 3)).build())) - .when(mappingContext) - .read(ROOT_ID); - doReturn(Optional.of(toIndex(1))) - .when(mappingContext) - .read(SPECIFIC_ID_1); - doReturn(Optional.absent()) - .when(mappingContext) - .read(SPECIFIC_ID_4); - } - - @Test - public void testGetAll() throws Exception { - final List disabledInterfaces = manager.getDisabledInterfaces(mappingContext); - assertThat(disabledInterfaces, hasItems(1, 2, 3)); - } - - @Test - public void testCheckOne() throws Exception { - assertTrue(manager.isInterfaceDisabled(1, mappingContext)); - assertFalse(manager.isInterfaceDisabled(4, mappingContext)); - } - - @Test - public void testDisable() throws Exception { - manager.disableInterface(1, mappingContext); - verify(mappingContext).put(SPECIFIC_ID_1, toIndex(1)); - } - - @Test - public void testRemoveDisability() throws Exception { - manager.removeDisabledInterface(1, mappingContext); - verify(mappingContext).delete(SPECIFIC_ID_1); - } - - private List toIndices(final int... indices) { - return Arrays.stream(indices) - .mapToObj(this::toIndex) - .collect(Collectors.toList()); - } - - private DisabledInterfaceIndex toIndex(final int idx) { - return new DisabledInterfaceIndexBuilder() - .setIndex(idx) - .build(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/V3poModuleTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/V3poModuleTest.java deleted file mode 100644 index 19aa2c98b..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/V3poModuleTest.java +++ /dev/null @@ -1,96 +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.honeycomb.translate.v3po; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.Matchers.empty; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.inject.Guice; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import com.google.inject.testing.fieldbinder.Bind; -import com.google.inject.testing.fieldbinder.BoundFieldModule; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; -import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; -import io.fd.honeycomb.translate.write.WriterFactory; -import java.util.HashSet; -import java.util.Set; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -public class V3poModuleTest { - - @Named("honeycomb-context") - @Bind - @Mock - private MappingContext mappingContext; - - @Named("honeycomb-initializer") - @Bind - @Mock - private DataBroker honeycombInitializer; - - @Named("honeycomb-context") - @Bind - @Mock - private DataBroker honeycombContext; - - @Bind - @Mock - private FutureJVppCore futureJVppCore; - - @Inject - private Set readerFactories = new HashSet<>(); - - @Inject - private Set writerFactories = new HashSet<>(); - - @Before - public void setUp() { - initMocks(this); - Guice.createInjector(new V3poModule(), BoundFieldModule.of(this)).injectMembers(this); - } - - @Test - public void testReaderFactories() throws Exception { - assertThat(readerFactories, is(not(empty()))); - - // Test registration process (all dependencies present, topological order of readers does exist, etc.) - final CompositeReaderRegistryBuilder registryBuilder = new CompositeReaderRegistryBuilder(); - readerFactories.stream().forEach(factory -> factory.init(registryBuilder)); - assertNotNull(registryBuilder.build()); - } - - @Test - public void testWriterFactories() throws Exception { - assertThat(writerFactories, is(not(empty()))); - - // Test registration process (all dependencies present, topological order of writers does exist, etc.) - final FlatWriterRegistryBuilder registryBuilder = new FlatWriterRegistryBuilder(); - writerFactories.stream().forEach(factory -> factory.init(registryBuilder)); - assertNotNull(registryBuilder.build()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/AclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/AclCustomizerTest.java deleted file mode 100644 index 53ff77927..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/AclCustomizerTest.java +++ /dev/null @@ -1,156 +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.honeycomb.translate.v3po.interfaces; - -import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; - -import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.AclCustomizer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -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.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import org.junit.Test; -import org.mockito.Mock; -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.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class AclCustomizerTest extends WriterCustomizerTest { - - @Mock - private VppClassifierContextManager classifyTableContext; - - private AclCustomizer customizer; - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - - private static final int ACL_TABLE_INDEX = 0; - private static final String ACL_TABLE_NAME = "table0"; - - @Override - public void setUp() { - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - customizer = new AclCustomizer(api, new NamingContext("generatedInterfaceName", IFC_TEST_INSTANCE), - classifyTableContext); - } - - private InstanceIdentifier getAclId(final String name) { - return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation( - VppInterfaceAugmentation.class).child(Acl.class).child(Ingress.class); - } - - private Ingress generateAcl(final String tableName) { - final IngressBuilder builder = new IngressBuilder(); - final L2Acl l2Acl = new L2AclBuilder().setClassifyTable(tableName).build(); - builder.setL2Acl(l2Acl); - return builder.build(); - } - - private void whenInputAclSetInterfaceThenSuccess() { - doReturn(future(new InputAclSetInterfaceReply())).when(api) - .inputAclSetInterface(any(InputAclSetInterface.class)); - } - - private void whenInputAclSetInterfaceThenFailure() { - doReturn(failedFuture()).when(api).inputAclSetInterface(any(InputAclSetInterface.class)); - } - - private static InputAclSetInterface generateInputAclSetInterface(final byte isAdd, final int ifIndex, - final int l2TableIndex) { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = isAdd; - request.l2TableIndex = l2TableIndex; - request.ip4TableIndex = ~0; - request.ip6TableIndex = ~0; - request.swIfIndex = ifIndex; - return request; - } - - @Test - public void testCreate() throws Exception { - final Ingress acl = generateAcl(ACL_TABLE_NAME); - final InstanceIdentifier id = getAclId(IF_NAME); - - whenInputAclSetInterfaceThenSuccess(); - - customizer.writeCurrentAttributes(id, acl, writeContext); - - verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 1, IF_INDEX, ACL_TABLE_INDEX)); - } - - @Test - public void testCreateFailed() throws Exception { - final Ingress acl = generateAcl(ACL_TABLE_NAME); - final InstanceIdentifier id = getAclId(IF_NAME); - - whenInputAclSetInterfaceThenFailure(); - - try { - customizer.writeCurrentAttributes(id, acl, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 1, IF_INDEX, ACL_TABLE_INDEX)); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testDelete() throws Exception { - final Ingress acl = generateAcl(ACL_TABLE_NAME); - final InstanceIdentifier id = getAclId(IF_NAME); - - whenInputAclSetInterfaceThenSuccess(); - - customizer.deleteCurrentAttributes(id, acl, writeContext); - - verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 0, IF_INDEX, ACL_TABLE_INDEX)); - } - - @Test - public void testDeleteFailed() throws Exception { - final Ingress acl = generateAcl(ACL_TABLE_NAME); - final InstanceIdentifier id = getAclId(IF_NAME); - - whenInputAclSetInterfaceThenFailure(); - - try { - customizer.deleteCurrentAttributes(id, acl, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).inputAclSetInterface(generateInputAclSetInterface((byte) 0, IF_INDEX, ACL_TABLE_INDEX)); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/GreCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/GreCustomizerTest.java deleted file mode 100644 index ee0d8fc23..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/GreCustomizerTest.java +++ /dev/null @@ -1,197 +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.honeycomb.translate.v3po.interfaces; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import com.google.common.net.InetAddresses; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.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.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.GreBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.GreAddDelTunnel; -import io.fd.vpp.jvpp.core.dto.GreAddDelTunnelReply; - -public class GreCustomizerTest extends WriterCustomizerTest { - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private final String IFACE_NAME = "eth0"; - private final int IFACE_ID = 1; - private InstanceIdentifier id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) - .augmentation(VppInterfaceAugmentation.class).child(Gre.class); - private static final byte ADD_GRE = 1; - private static final byte DEL_GRE = 0; - - private GreCustomizer customizer; - - @Override - public void setUp() throws Exception { - InterfaceTypeTestUtils.setupWriteContext(writeContext, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.GreTunnel.class); - customizer = new GreCustomizer(api, new NamingContext("generateInterfaceNAme", IFC_TEST_INSTANCE)); - } - - private void whenGreAddDelTunnelThenSuccess() { - final GreAddDelTunnelReply reply = new GreAddDelTunnelReply(); - reply.swIfIndex = IFACE_ID; - doReturn(future(reply)).when(api).greAddDelTunnel(any(GreAddDelTunnel.class)); - } - - private void whenGreAddDelTunnelThenFailure() { - doReturn(failedFuture()).when(api).greAddDelTunnel(any(GreAddDelTunnel.class)); - } - - private GreAddDelTunnel verifyGreAddDelTunnelWasInvoked(final Gre gre) throws VppInvocationException { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(GreAddDelTunnel.class); - verify(api).greAddDelTunnel(argumentCaptor.capture()); - final GreAddDelTunnel actual = argumentCaptor.getValue(); - assertEquals(0, actual.isIpv6); - assertArrayEquals(InetAddresses.forString(gre.getSrc().getIpv4Address().getValue()).getAddress(), - actual.srcAddress); - assertArrayEquals(InetAddresses.forString(gre.getDst().getIpv4Address().getValue()).getAddress(), - actual.dstAddress); - assertEquals(gre.getOuterFibId().intValue(), actual.outerFibId); - return actual; - } - - private void verifyGreAddWasInvoked(final Gre gre) throws VppInvocationException { - final GreAddDelTunnel actual = verifyGreAddDelTunnelWasInvoked(gre); - assertEquals(ADD_GRE, actual.isAdd); - } - - private void verifyGreDeleteWasInvoked(final Gre gre) throws VppInvocationException { - final GreAddDelTunnel actual = verifyGreAddDelTunnelWasInvoked(gre); - assertEquals(DEL_GRE, actual.isAdd); - } - - private static Gre generateGre() { - final GreBuilder builder = new GreBuilder(); - builder.setSrc(new IpAddress(new Ipv4Address("192.168.20.10"))); - builder.setDst(new IpAddress(new Ipv4Address("192.168.20.11"))); - builder.setOuterFibId(Long.valueOf(123)); - return builder.build(); - } - - @Test - public void testWriteCurrentAttributes() throws Exception { - final Gre gre = generateGre(); - - whenGreAddDelTunnelThenSuccess(); - - noMappingDefined(mappingContext, IFACE_NAME, IFC_TEST_INSTANCE); - - customizer.writeCurrentAttributes(id, gre, writeContext); - verifyGreAddWasInvoked(gre); - verify(mappingContext).put(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE)), - eq(mapping(IFACE_NAME, IFACE_ID).get())); - } - - @Test - public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception { - final Gre gre = generateGre(); - - whenGreAddDelTunnelThenSuccess(); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_TEST_INSTANCE); - - customizer.writeCurrentAttributes(id, gre, writeContext); - verifyGreAddWasInvoked(gre); - - // Remove the first mapping before putting in the new one - verify(mappingContext).delete(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE))); - verify(mappingContext).put(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE)), eq(mapping(IFACE_NAME, IFACE_ID).get())); - } - - @Test - public void testWriteCurrentAttributesFailed() throws Exception { - final Gre gre = generateGre(); - - whenGreAddDelTunnelThenFailure(); - - try { - customizer.writeCurrentAttributes(id, gre, writeContext); - } catch (WriteFailedException.CreateFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyGreAddWasInvoked(gre); - // Mapping not stored due to failure - verify(mappingContext, times(0)).put(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE)), eq(mapping( - IFACE_NAME, 0).get())); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testUpdateCurrentAttributes() throws Exception { - try { - customizer.updateCurrentAttributes(id, generateGre(), generateGre(), writeContext); - } catch (WriteFailedException.UpdateFailedException e) { - assertEquals(UnsupportedOperationException.class, e.getCause().getClass()); - return; - } - fail("WriteFailedException.UpdateFailedException was expected"); - } - - @Test - public void testDeleteCurrentAttributes() throws Exception { - final Gre gre = generateGre(); - - whenGreAddDelTunnelThenSuccess(); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_TEST_INSTANCE); - - customizer.deleteCurrentAttributes(id, gre, writeContext); - verifyGreDeleteWasInvoked(gre); - verify(mappingContext).delete(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE))); - } - - @Test - public void testDeleteCurrentAttributesaFailed() throws Exception { - final Gre gre = generateGre(); - - whenGreAddDelTunnelThenFailure(); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_TEST_INSTANCE); - - try { - customizer.deleteCurrentAttributes(id, gre, writeContext); - } catch (WriteFailedException.DeleteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyGreDeleteWasInvoked(gre); - verify(mappingContext, times(0)).delete(eq(mappingIid(IFACE_NAME, IFC_TEST_INSTANCE))); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizerTest.java deleted file mode 100644 index 56abe58f6..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizerTest.java +++ /dev/null @@ -1,116 +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.honeycomb.translate.v3po.interfaces; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -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.InterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlags; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsReply; - -public class InterfaceCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { - private static final String IFACE_CTX_NAME = "interface-ctx"; - private static final String IF_NAME = "eth1"; - private static final int IF_INDEX = 1; - - private InterfaceCustomizer customizer; - private InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)); - - @Override - protected void setUp() throws Exception { - customizer = new InterfaceCustomizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME); - } - - @Test - public void testWrite() throws WriteFailedException { - final boolean enabled = true; - when(api.swInterfaceSetFlags(any())).thenReturn(future(new SwInterfaceSetFlagsReply())); - customizer.writeCurrentAttributes(IID, iface(enabled), writeContext); - verify(api).swInterfaceSetFlags(expectedRequest(enabled)); - } - - @Test - public void testWriteFailed() { - final boolean enabled = false; - when(api.swInterfaceSetFlags(any())).thenReturn(failedFuture()); - try { - customizer.writeCurrentAttributes(IID, iface(enabled), writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).swInterfaceSetFlags(expectedRequest(enabled)); - return; - } - fail("WriteFailedException expected"); - } - - @Test - public void testUpdate() throws WriteFailedException { - when(api.swInterfaceSetFlags(any())).thenReturn(future(new SwInterfaceSetFlagsReply())); - customizer.updateCurrentAttributes(IID, iface(false), iface(true), writeContext); - verify(api).swInterfaceSetFlags(expectedRequest(true)); - } - - @Test - public void testUpdateFailed() { - when(api.swInterfaceSetFlags(any())).thenReturn(failedFuture()); - try { - customizer.updateCurrentAttributes(IID, iface(false), iface(true), writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).swInterfaceSetFlags(expectedRequest(true)); - return; - } - fail("WriteFailedException expected"); - } - - @Test - public void testDelete() throws WriteFailedException { - customizer.deleteCurrentAttributes(IID, mock(Interface.class), writeContext); - verifyZeroInteractions(api); - } - - private Interface iface(final boolean enabled) { - return new InterfaceBuilder().setName(IF_NAME).setEnabled(enabled).build(); - } - - private SwInterfaceSetFlags expectedRequest(final boolean enabled) { - final SwInterfaceSetFlags request = new SwInterfaceSetFlags(); - request.deleted = 0; - request.adminUpDown = booleanToByte(enabled); - request.linkUpDown = booleanToByte(enabled); - request.swIfIndex = IF_INDEX; - return request; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceTypeTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceTypeTestUtils.java deleted file mode 100644 index 9ff5b1b2d..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceTypeTestUtils.java +++ /dev/null @@ -1,40 +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.honeycomb.translate.v3po.interfaces; - -import static org.mockito.Mockito.doReturn; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.ModificationCache; -import io.fd.honeycomb.translate.write.WriteContext; -import org.mockito.Matchers; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -final class InterfaceTypeTestUtils { - - private InterfaceTypeTestUtils() {} - - static void setupWriteContext(final WriteContext writeContext, final Class ifcType) { - doReturn(new ModificationCache()).when(writeContext).getModificationCache(); - doReturn(Optional.of(new InterfaceBuilder() - .setType(ifcType) - .build())).when(writeContext).readAfter(Matchers.any(InstanceIdentifier.class)); - } - -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/L2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/L2CustomizerTest.java deleted file mode 100644 index ec33295e2..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/L2CustomizerTest.java +++ /dev/null @@ -1,150 +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.honeycomb.translate.v3po.interfaces; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -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.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBased; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBased; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBasedBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Bridge; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2BridgeReply; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Xconnect; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2XconnectReply; - -public class L2CustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { - private static final String IFACE_CTX_NAME = "interface-ctx"; - private static final String BD_CTX_NAME = "bd-ctx"; - private static final String IF1_NAME = "eth1"; - private static final int IF1_INDEX = 1; - private static final String IF2_NAME = "eth2"; - private static final int IF2_INDEX = 2; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF1_NAME)) - .augmentation(VppInterfaceAugmentation.class).child(L2.class); - private static final String BD_NAME = "test_bd"; - private static final int BD_INDEX = 13; - - private L2Customizer customizer; - - @Override - protected void setUp() throws Exception { - customizer = new L2Customizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME), - new NamingContext("bdPrefix", BD_CTX_NAME)); - defineMapping(mappingContext, IF1_NAME, IF1_INDEX, IFACE_CTX_NAME); - defineMapping(mappingContext, IF2_NAME, IF2_INDEX, IFACE_CTX_NAME); - defineMapping(mappingContext, BD_NAME, BD_INDEX, BD_CTX_NAME); - } - - @Test - public void testWrite() throws WriteFailedException { - when(api.swInterfaceSetL2Xconnect(any())).thenReturn(future(new SwInterfaceSetL2XconnectReply())); - customizer.writeCurrentAttributes(IID, l2(xconnectBased()), writeContext); - verify(api).swInterfaceSetL2Xconnect(xconnectRequest(true)); - } - - @Test - public void testWriteFailed() { - when(api.swInterfaceSetL2Bridge(any())).thenReturn(failedFuture()); - try { - customizer.writeCurrentAttributes(IID, l2(bridgeBased(false)), writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).swInterfaceSetL2Bridge(bridgeRequest(false, true)); - return; - } - fail("WriteFailedException expected"); - } - - @Test - public void testUpdate() throws WriteFailedException { - when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply())); - customizer.updateCurrentAttributes(IID, l2(bridgeBased(false)), l2(bridgeBased(true)), writeContext); - verify(api).swInterfaceSetL2Bridge(bridgeRequest(true, true)); - } - - @Test - public void testDelete() throws WriteFailedException { - when(api.swInterfaceSetL2Xconnect(any())).thenReturn(future(new SwInterfaceSetL2XconnectReply())); - customizer.deleteCurrentAttributes(IID, l2(xconnectBased()), writeContext); - verify(api).swInterfaceSetL2Xconnect(xconnectRequest(false)); - } - - @Test - public void testDeleteFailed() { - when(api.swInterfaceSetL2Bridge(any())).thenReturn(failedFuture()); - try { - customizer.deleteCurrentAttributes(IID, l2(bridgeBased(true)), writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).swInterfaceSetL2Bridge(bridgeRequest(true, false)); - return; - } - fail("WriteFailedException expected"); - } - - private XconnectBased xconnectBased() { - return new XconnectBasedBuilder().setXconnectOutgoingInterface(IF2_NAME).build(); - } - - private SwInterfaceSetL2Xconnect xconnectRequest(final boolean enable) { - final SwInterfaceSetL2Xconnect request = new SwInterfaceSetL2Xconnect(); - request.rxSwIfIndex = IF1_INDEX; - request.txSwIfIndex = IF2_INDEX; - request.enable = booleanToByte(enable); - return request; - } - - private BridgeBased bridgeBased(final boolean bvi) { - return new BridgeBasedBuilder().setBridgedVirtualInterface(bvi) - .setBridgeDomain(BD_NAME).setSplitHorizonGroup((short) 123).build(); - } - - private SwInterfaceSetL2Bridge bridgeRequest(final boolean bvi, final boolean enable) { - final SwInterfaceSetL2Bridge request = new SwInterfaceSetL2Bridge(); - request.bdId = BD_INDEX; - request.rxSwIfIndex = IF1_INDEX; - request.bvi = booleanToByte(bvi); - request.enable = booleanToByte(enable); - request.shg = 123; - return request; - } - - - private L2 l2(final Interconnection interconnection) { - return new L2Builder().setInterconnection(interconnection).build(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/LoopbackCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/LoopbackCustomizerTest.java deleted file mode 100644 index 60af7a143..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/LoopbackCustomizerTest.java +++ /dev/null @@ -1,105 +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.honeycomb.translate.v3po.interfaces; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import io.fd.vpp.jvpp.core.dto.CreateLoopback; -import io.fd.vpp.jvpp.core.dto.CreateLoopbackReply; -import io.fd.vpp.jvpp.core.dto.DeleteLoopback; -import io.fd.vpp.jvpp.core.dto.DeleteLoopbackReply; -import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -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.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Loopback; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.LoopbackBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class LoopbackCustomizerTest extends WriterCustomizerTest { - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private LoopbackCustomizer loopCustomizer; - - @Override - public void setUp() throws Exception { - InterfaceTypeTestUtils.setupWriteContext(writeContext, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Loopback.class); - loopCustomizer = new LoopbackCustomizer(api, new NamingContext("ifcintest", IFC_TEST_INSTANCE)); - } - - @Test - public void testCreate() throws Exception { - doAnswer(new Answer() { - - int idx = 0; - - @Override - public Object answer(final InvocationOnMock invocation) throws Throwable { - final CreateLoopbackReply t = new CreateLoopbackReply(); - t.swIfIndex = idx++; - return future(t); - } - }).when(api).createLoopback(any(CreateLoopback.class)); - - loopCustomizer.writeCurrentAttributes(getLoopbackId("loop"), getLoopbackData("ff:ff:ff:ff:ff:ff"), writeContext); - loopCustomizer.writeCurrentAttributes(getLoopbackId("loop2"), getLoopbackData("ff:ff:ff:ff:ff:ff"), writeContext); - - verify(api, times(2)).createLoopback(any(CreateLoopback.class)); - verify(mappingContext).put(eq(mappingIid("loop", IFC_TEST_INSTANCE)), eq( - mapping("loop", 0).get())); - verify(mappingContext).put(eq(mappingIid("loop2", IFC_TEST_INSTANCE)), eq( - mapping("loop2", 1).get())); - } - - @Test - public void testDelete() throws Exception { - final CreateLoopbackReply t = new CreateLoopbackReply(); - t.swIfIndex = 0; - doReturn(future(t)).when(api).createLoopback(any(CreateLoopback.class)); - - doReturn(future(new DeleteLoopbackReply())).when(api).deleteLoopback(any(DeleteLoopback.class)); - - loopCustomizer.writeCurrentAttributes(getLoopbackId("loop"), getLoopbackData("ff:ff:ff:ff:ff:ff"), writeContext); - defineMapping(mappingContext, "loop", 1, IFC_TEST_INSTANCE); - loopCustomizer.deleteCurrentAttributes(getLoopbackId("loop"), getLoopbackData("ff:ff:ff:ff:ff:ff"), writeContext); - - verify(api).createLoopback(any(CreateLoopback.class)); - verify(api).deleteLoopback(any(DeleteLoopback.class)); - verify(mappingContext).delete(eq(mappingIid("loop", IFC_TEST_INSTANCE))); - } - - private InstanceIdentifier getLoopbackId(final String loop) { - return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(loop)).augmentation( - VppInterfaceAugmentation.class).child(Loopback.class); - } - - private Loopback getLoopbackData(final String mac) { - return new LoopbackBuilder().setMac(new PhysAddress(mac)).build(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizerTest.java deleted file mode 100644 index 922d072a4..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizerTest.java +++ /dev/null @@ -1,97 +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.honeycomb.translate.v3po.interfaces; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -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.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArpBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.ProxyArpAddDel; -import io.fd.vpp.jvpp.core.dto.ProxyArpAddDelReply; - -public class ProxyArpCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { - private static final String IF_NAME = "eth1"; - - private ProxyArpCustomizer customizer; - - @Override - public void setUp() throws Exception { - customizer = new ProxyArpCustomizer(api); - } - - @Test - public void testWrite() throws WriteFailedException { - when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply())); - customizer.writeCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); - verify(api).proxyArpAddDel(expectedRequest(true)); - } - - @Test(expected = WriteFailedException.class) - public void testWriteFailed() throws WriteFailedException { - when(api.proxyArpAddDel(any())).thenReturn(failedFuture()); - customizer.writeCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); - } - - @Test(expected = WriteFailedException.UpdateFailedException.class) - public void testUpdate() throws WriteFailedException.UpdateFailedException { - customizer.updateCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), proxyArp(), writeContext); - } - - @Test - public void testDelete() throws WriteFailedException { - when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply())); - customizer.deleteCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); - verify(api).proxyArpAddDel(expectedRequest(false)); - } - - @Test(expected = WriteFailedException.DeleteFailedException.class) - public void testDeleteFailed() throws WriteFailedException { - when(api.proxyArpAddDel(any())).thenReturn(failedFuture()); - customizer.deleteCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); - } - - private ProxyArp proxyArp() { - return new ProxyArpBuilder().setVrfId(123L).setHighAddr(new Ipv4AddressNoZone("10.1.1.2")) - .setLowAddr(new Ipv4AddressNoZone("10.1.1.1")).build(); - } - - private ProxyArpAddDel expectedRequest(final boolean isAdd) { - final ProxyArpAddDel request = new ProxyArpAddDel(); - request.isAdd = booleanToByte(isAdd); - request.vrfId = 123; - request.lowAddress = new byte[]{10,1,1,1}; - request.hiAddress = new byte[]{10,1,1,2}; - return request; - } - - private InstanceIdentifier getProxyArpId(final String eth0) { - return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(eth0)).augmentation( - VppInterfaceAugmentation.class).child(ProxyArp.class); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RewriteCustomizerTest.java deleted file mode 100644 index 035a0f2d5..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RewriteCustomizerTest.java +++ /dev/null @@ -1,198 +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.honeycomb.translate.v3po.interfaces; - -import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; - -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.TagRewriteOperation; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.L2InterfaceVlanTagRewrite; -import io.fd.vpp.jvpp.core.dto.L2InterfaceVlanTagRewriteReply; -import org.junit.Assert; -import org.junit.Test; -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.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1q; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.RewriteBuilder; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class RewriteCustomizerTest extends WriterCustomizerTest { - - private NamingContext namingContext; - private RewriteCustomizer customizer; - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final String VLAN_IF_NAME = "local0.1"; - private static final int VLAN_IF_ID = 1; - private static final int VLAN_IF_INDEX = 11; - private InstanceIdentifier VLAN_IID; - - @Override - public void setUp() throws Exception { - namingContext = new NamingContext("generatedSubInterfaceName", IFC_TEST_INSTANCE); - customizer = new RewriteCustomizer(api, namingContext); - VLAN_IID = getVlanTagRewriteId(IF_NAME, VLAN_IF_ID); - defineMapping(mappingContext, VLAN_IF_NAME, VLAN_IF_INDEX, IFC_TEST_INSTANCE); - } - - private static InstanceIdentifier getVlanTagRewriteId(final String name, final long index) { - final Class> child = (Class) Rewrite.class; - final InstanceIdentifier id = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(index)) - .child(child); - return id; - } - - private Rewrite generateRewrite(final TagRewriteOperation op) { - final RewriteBuilder builder = new RewriteBuilder(); - builder.setPopTags((short) op.getPopTags()); - builder.setVlanType(_802dot1q.class); - return builder.build(); - } - - private L2InterfaceVlanTagRewrite generateL2InterfaceVlanTagRewrite(final int swIfIndex, - final TagRewriteOperation op) { - final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite(); - request.swIfIndex = swIfIndex; - request.vtrOp = op.ordinal(); - request.pushDot1Q = 1; - return request; - } - - /** - * Positive response - */ - private void whenL2InterfaceVlanTagRewriteThenSuccess() { - doReturn(future(new L2InterfaceVlanTagRewriteReply())).when(api) - .l2InterfaceVlanTagRewrite(any(L2InterfaceVlanTagRewrite.class)); - } - - /** - * Failure response send - */ - private void whenL2InterfaceVlanTagRewriteThenFailure() { - doReturn(failedFuture()).when(api).l2InterfaceVlanTagRewrite(any(L2InterfaceVlanTagRewrite.class)); - } - - private void verifyL2InterfaceVlanTagRewriteDeleteWasInvoked() throws VppInvocationException { - final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite(); - request.swIfIndex = VLAN_IF_INDEX; - verify(api).l2InterfaceVlanTagRewrite(request); - } - - @Test - public void testCreate() throws Exception { - final TagRewriteOperation op = TagRewriteOperation.pop_2; - final Rewrite vlanTagRewrite = generateRewrite(op); - - whenL2InterfaceVlanTagRewriteThenSuccess(); - - customizer.writeCurrentAttributes(VLAN_IID, vlanTagRewrite, writeContext); - - verify(api).l2InterfaceVlanTagRewrite(generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, op)); - } - - @Test - public void testCreateFailed() throws Exception { - final TagRewriteOperation op = TagRewriteOperation.pop_2; - final Rewrite vlanTagRewrite = generateRewrite(op); - - whenL2InterfaceVlanTagRewriteThenFailure(); - - try { - customizer.writeCurrentAttributes(VLAN_IID, vlanTagRewrite, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).l2InterfaceVlanTagRewrite(generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, op)); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testUpdate() throws Exception { - final Rewrite before = generateRewrite(TagRewriteOperation.pop_2); - final Rewrite after = generateRewrite(TagRewriteOperation.pop_1); - - whenL2InterfaceVlanTagRewriteThenSuccess(); - - customizer.updateCurrentAttributes(VLAN_IID, before, after, writeContext); - - verify(api) - .l2InterfaceVlanTagRewrite(generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, TagRewriteOperation.pop_1)); - } - - @Test - public void testUpdateFailed() throws Exception { - final Rewrite before = generateRewrite(TagRewriteOperation.pop_2); - final Rewrite after = generateRewrite(TagRewriteOperation.pop_1); - - whenL2InterfaceVlanTagRewriteThenFailure(); - - try { - customizer.updateCurrentAttributes(VLAN_IID, before, after, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api) - .l2InterfaceVlanTagRewrite( - generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, TagRewriteOperation.pop_1)); - return; - } - fail("WriteFailedException.UpdateFailedException was expected"); - } - - @Test - public void testDelete() throws Exception { - whenL2InterfaceVlanTagRewriteThenSuccess(); - - customizer.deleteCurrentAttributes(VLAN_IID, null, writeContext); - - verifyL2InterfaceVlanTagRewriteDeleteWasInvoked(); - } - - @Test - public void testDeleteFailed() throws Exception { - whenL2InterfaceVlanTagRewriteThenFailure(); - - try { - customizer.deleteCurrentAttributes(VLAN_IID, null, writeContext); - } catch (WriteFailedException e) { - Assert.assertTrue(e.getCause() instanceof VppBaseCallException); - verifyL2InterfaceVlanTagRewriteDeleteWasInvoked(); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizerTest.java deleted file mode 100644 index a6a0b48f0..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizerTest.java +++ /dev/null @@ -1,97 +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.honeycomb.translate.v3po.interfaces; - -import static org.mockito.Matchers.any; -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.core.dto.SwInterfaceSetTable; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetTableReply; -import org.junit.Test; -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.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Routing; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.RoutingBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class RoutingCustomizerTest extends WriterCustomizerTest { - private static final String IFACE_CTX_NAME = "interface-ctx"; - private static final String IF_NAME = "eth1"; - private static final int IF_INDEX = 1; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(VppInterfaceAugmentation.class).child(Routing.class); - - private RoutingCustomizer customizer; - - @Override - protected void setUp() throws Exception { - customizer = new RoutingCustomizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME); - } - - @Test - public void testWrite() throws WriteFailedException { - final int vrfId = 123; - when(api.swInterfaceSetTable(any())).thenReturn(future(new SwInterfaceSetTableReply())); - customizer.writeCurrentAttributes(IID, routing(vrfId), writeContext); - verify(api).swInterfaceSetTable(expectedRequest(vrfId)); - } - - @Test(expected = WriteFailedException.class) - public void testWriteFailed() throws WriteFailedException { - when(api.swInterfaceSetTable(any())).thenReturn(failedFuture()); - customizer.writeCurrentAttributes(IID, routing(213), writeContext); - } - - @Test(expected = WriteFailedException.class) - public void testUpdateFailed() throws WriteFailedException { - when(api.swInterfaceSetTable(any())).thenReturn(failedFuture()); - customizer.updateCurrentAttributes(IID, routing(123L), routing(321L), writeContext); - } - - @Test - public void testDelete() throws WriteFailedException { - when(api.swInterfaceSetTable(any())).thenReturn(future(new SwInterfaceSetTableReply())); - customizer.deleteCurrentAttributes(IID, routing(123), writeContext); - verify(api).swInterfaceSetTable(expectedRequest(0)); - } - - @Test(expected = WriteFailedException.DeleteFailedException.class) - public void testDeleteFailed() throws WriteFailedException { - when(api.swInterfaceSetTable(any())).thenReturn(failedFuture()); - customizer.deleteCurrentAttributes(IID, routing(123), writeContext); - } - - private Routing routing(final long vrfId) { - return new RoutingBuilder().setIpv4VrfId(vrfId).build(); - } - - private SwInterfaceSetTable expectedRequest(final int vrfId) { - final SwInterfaceSetTable request = new SwInterfaceSetTable(); - request.isIpv6 = 0; - request.swIfIndex = IF_INDEX; - request.vrfId = vrfId; - return request; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizerTest.java deleted file mode 100644 index bcf3cad6d..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizerTest.java +++ /dev/null @@ -1,258 +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.honeycomb.translate.v3po.interfaces; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import java.util.Arrays; -import java.util.List; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qTagVlanType; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId; -import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan; -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.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTagBuilder; -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.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1ad; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTaggedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.MatchBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.TagsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.CreateSubif; -import io.fd.vpp.jvpp.core.dto.CreateSubifReply; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlags; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsReply; - -public class SubInterfaceCustomizerTest extends WriterCustomizerTest { - - private NamingContext namingContext; - private SubInterfaceCustomizer customizer; - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String SUPER_IF_NAME = "local0"; - private static final int SUPER_IF_ID = 1; - private static final String SUB_IFACE_NAME = "local0.11"; - private static final int SUBIF_INDEX = 11; - - private static final short STAG_ID = 100; - private static final short CTAG_ID = 200; - private static final short CTAG_ANY_ID = 0; // only the *IdAny flag is set - - private final Tag STAG_100; - private final Tag CTAG_200; - private final Tag CTAG_ANY; - - public SubInterfaceCustomizerTest() { - STAG_100 = generateTag((short) 0, SVlan.class, new Dot1qTag.VlanId(new Dot1qVlanId((int) STAG_ID))); - CTAG_200 = generateTag((short) 1, CVlan.class, new Dot1qTag.VlanId(new Dot1qVlanId(200))); - CTAG_ANY = generateTag((short) 1, CVlan.class, new Dot1qTag.VlanId(Dot1qTag.VlanId.Enumeration.Any)); - } - - @Override - public void setUp() throws Exception { - namingContext = new NamingContext("generatedSubInterfaceName", IFC_TEST_INSTANCE); - customizer = new SubInterfaceCustomizer(api, namingContext); - defineMapping(mappingContext, SUB_IFACE_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); - defineMapping(mappingContext, SUPER_IF_NAME, SUPER_IF_ID, IFC_TEST_INSTANCE); - } - - private SubInterface generateSubInterface(final boolean enabled, final List tagList) { - SubInterfaceBuilder builder = new SubInterfaceBuilder(); - builder.setVlanType(_802dot1ad.class); - builder.setIdentifier(11L); - final TagsBuilder tags = new TagsBuilder(); - - tags.setTag(tagList); - - builder.setTags(tags.build()); - - builder.setMatch(generateMatch()); - builder.setEnabled(enabled); - return builder.build(); - } - - private static Tag generateTag(final short index, final Class tagType, - final Dot1qTag.VlanId vlanId) { - TagBuilder tag = new TagBuilder(); - tag.setIndex(index); - tag.setKey(new TagKey(index)); - final Dot1qTagBuilder dtag = new Dot1qTagBuilder(); - dtag.setTagType(tagType); - dtag.setVlanId(vlanId); - tag.setDot1qTag(dtag.build()); - return tag.build(); - } - - private static Match generateMatch() { - final MatchBuilder match = new MatchBuilder(); - final VlanTaggedBuilder tagged = new VlanTaggedBuilder(); - tagged.setMatchExactTags(true); - match.setMatchType( - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.VlanTaggedBuilder() - .setVlanTagged(tagged.build()).build()); - return match.build(); - } - - private CreateSubif generateSubInterfaceRequest(final int superIfId, final short innerVlanId, - final boolean isInnerAny) { - CreateSubif request = new CreateSubif(); - request.subId = 11; - request.swIfIndex = superIfId; - request.twoTags = 1; - request.innerVlanId = innerVlanId; - request.innerVlanIdAny = (byte) (isInnerAny - ? 1 - : 0); - request.dot1Ad = 1; - request.outerVlanId = STAG_ID; - return request; - } - - private SwInterfaceSetFlags generateSwInterfaceEnableRequest(final int swIfIndex) { - SwInterfaceSetFlags request = new SwInterfaceSetFlags(); - request.swIfIndex = swIfIndex; - request.adminUpDown = 1; - return request; - } - - private InstanceIdentifier getSubInterfaceId(final String name, final long index) { - return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(index)); - } - - private void whenCreateSubifThenSuccess() { - doReturn(future(new CreateSubifReply())).when(api).createSubif(any(CreateSubif.class)); - } - - /** - * Failure response send - */ - private void whenCreateSubifThenFailure() { - doReturn(failedFuture()).when(api).createSubif(any(CreateSubif.class)); - } - - private void whenSwInterfaceSetFlagsThenSuccess() { - doReturn(future(new SwInterfaceSetFlagsReply())).when(api).swInterfaceSetFlags(any(SwInterfaceSetFlags.class)); - } - - private SwInterfaceSetFlags verifySwInterfaceSetFlagsWasInvoked(final SwInterfaceSetFlags expected) - throws VppBaseCallException { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(SwInterfaceSetFlags.class); - verify(api).swInterfaceSetFlags(argumentCaptor.capture()); - final SwInterfaceSetFlags actual = argumentCaptor.getValue(); - - assertEquals(expected.swIfIndex, actual.swIfIndex); - assertEquals(expected.adminUpDown, actual.adminUpDown); - return actual; - } - - @Test - public void testCreateTwoTags() throws Exception { - final SubInterface subInterface = generateSubInterface(false, Arrays.asList(STAG_100, CTAG_200)); - final InstanceIdentifier id = getSubInterfaceId(SUPER_IF_NAME, SUBIF_INDEX); - - whenCreateSubifThenSuccess(); - whenSwInterfaceSetFlagsThenSuccess(); - - customizer.writeCurrentAttributes(id, subInterface, writeContext); - - verify(api).createSubif(generateSubInterfaceRequest(SUPER_IF_ID, CTAG_ID, false)); - verify(mappingContext) - .put(eq(mappingIid(SUB_IFACE_NAME, IFC_TEST_INSTANCE)), eq( - mapping(SUB_IFACE_NAME, 0).get())); - } - - @Test - public void testCreateDot1qAnyTag() throws Exception { - final SubInterface subInterface = generateSubInterface(false, Arrays.asList(STAG_100, CTAG_ANY)); - final InstanceIdentifier id = getSubInterfaceId(SUPER_IF_NAME, SUBIF_INDEX); - - whenCreateSubifThenSuccess(); - whenSwInterfaceSetFlagsThenSuccess(); - - customizer.writeCurrentAttributes(id, subInterface, writeContext); - - verify(api).createSubif(generateSubInterfaceRequest(SUPER_IF_ID, CTAG_ANY_ID, true)); - verify(mappingContext) - .put(eq(mappingIid(SUB_IFACE_NAME, IFC_TEST_INSTANCE)), eq( - mapping(SUB_IFACE_NAME, 0).get())); - } - - @Test - public void testCreateFailed() throws Exception { - final SubInterface subInterface = generateSubInterface(false, Arrays.asList(STAG_100, CTAG_200)); - final InstanceIdentifier id = getSubInterfaceId(SUPER_IF_NAME, SUBIF_INDEX); - - whenCreateSubifThenFailure(); - - try { - customizer.writeCurrentAttributes(id, subInterface, writeContext); - } catch (WriteFailedException.CreateFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).createSubif(generateSubInterfaceRequest(SUPER_IF_ID, CTAG_ID, false)); - verify(mappingContext, times(0)).put( - eq(mappingIid(SUPER_IF_NAME, IFC_TEST_INSTANCE)), - eq(mapping(SUPER_IF_NAME, 0).get())); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testUpdate() throws Exception { - final List tags = Arrays.asList(STAG_100, CTAG_200); - final SubInterface before = generateSubInterface(false, tags); - final SubInterface after = generateSubInterface(true, tags); - final InstanceIdentifier id = getSubInterfaceId(SUPER_IF_NAME, SUBIF_INDEX); - - whenSwInterfaceSetFlagsThenSuccess(); - customizer.updateCurrentAttributes(id, before, after, writeContext); - - verifySwInterfaceSetFlagsWasInvoked(generateSwInterfaceEnableRequest(SUBIF_INDEX)); - } - - @Test(expected = UnsupportedOperationException.class) - public void testDelete() throws Exception { - final SubInterface subInterface = generateSubInterface(false, Arrays.asList(STAG_100, CTAG_200)); - customizer.deleteCurrentAttributes(null, subInterface, writeContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2CustomizerTest.java deleted file mode 100644 index 3538a5c3b..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2CustomizerTest.java +++ /dev/null @@ -1,109 +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.honeycomb.translate.v3po.interfaces; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -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.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Bridge; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2BridgeReply; - -public class SubInterfaceL2CustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { - private static final String IFACE_CTX_NAME = "interface-ctx"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUBIF_NAME = "local0.0"; - private static final int SUBIF_INDEX = 11; - private static final long SUBIF_ID = 0; - - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(L2.class); - - - private static final String BD_CTX_NAME = "bd-ctx"; - private static final String BD_NAME = "test_bd"; - private static final int BD_INDEX = 13; - - private SubInterfaceL2Customizer customizer; - - @Override - protected void setUp() throws Exception { - customizer = new SubInterfaceL2Customizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME), - new NamingContext("bdPrefix", BD_CTX_NAME)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFACE_CTX_NAME); - defineMapping(mappingContext, BD_NAME, BD_INDEX, BD_CTX_NAME); - } - - @Test - public void testWrite() throws WriteFailedException { - final boolean bvi = true; - when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply())); - customizer.writeCurrentAttributes(IID, l2(bvi), writeContext); - verify(api).swInterfaceSetL2Bridge(bridgeRequest(bvi, true)); - } - - @Test - public void testUpdate() throws WriteFailedException { - final boolean bvi = false; - when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply())); - customizer.updateCurrentAttributes(IID, l2(true), l2(bvi), writeContext); - verify(api).swInterfaceSetL2Bridge(bridgeRequest(bvi, true)); - } - - @Test - public void testDelete() throws WriteFailedException { - final boolean bvi = true; - when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply())); - customizer.deleteCurrentAttributes(IID, l2(bvi), writeContext); - verify(api).swInterfaceSetL2Bridge(bridgeRequest(bvi, false)); - } - - private L2 l2(final boolean bvi) { - return new L2Builder().setInterconnection(new BridgeBasedBuilder().setBridgedVirtualInterface(bvi) - .setBridgeDomain(BD_NAME).setSplitHorizonGroup((short) 123).build()).build(); - } - - private SwInterfaceSetL2Bridge bridgeRequest(final boolean bvi, final boolean enable) { - final SwInterfaceSetL2Bridge request = new SwInterfaceSetL2Bridge(); - request.bdId = BD_INDEX; - request.rxSwIfIndex = SUBIF_INDEX; - request.bvi = booleanToByte(bvi); - request.enable = booleanToByte(enable); - request.shg = 123; - return request; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/TapCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/TapCustomizerTest.java deleted file mode 100644 index 6e9fbe697..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/TapCustomizerTest.java +++ /dev/null @@ -1,129 +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.honeycomb.translate.v3po.interfaces; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -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.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.TapBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.TapConnect; -import io.fd.vpp.jvpp.core.dto.TapConnectReply; -import io.fd.vpp.jvpp.core.dto.TapDelete; -import io.fd.vpp.jvpp.core.dto.TapDeleteReply; -import io.fd.vpp.jvpp.core.dto.TapModify; -import io.fd.vpp.jvpp.core.dto.TapModifyReply; - -public class TapCustomizerTest extends WriterCustomizerTest { - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private TapCustomizer tapCustomizer; - - @Override - public void setUp() throws Exception { - InterfaceTypeTestUtils.setupWriteContext(writeContext, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap.class); - tapCustomizer = new TapCustomizer(api, new NamingContext("ifcintest", IFC_TEST_INSTANCE)); - } - - @Test - public void testCreate() throws Exception { - doAnswer(new Answer() { - - int idx = 0; - - @Override - public Object answer(final InvocationOnMock invocation) throws Throwable { - final TapConnectReply t = new TapConnectReply(); - t.swIfIndex = idx++; - return future(t); - } - }).when(api).tapConnect(any(TapConnect.class)); - - tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext); - tapCustomizer.writeCurrentAttributes(getTapId("tap2"), getTapData("tap2", "ff:ff:ff:ff:ff:ff"), writeContext); - - verify(api, times(2)).tapConnect(any(TapConnect.class)); - verify(mappingContext).put(eq(mappingIid("tap", IFC_TEST_INSTANCE)), eq( - mapping("tap", 0).get())); - verify(mappingContext).put(eq(mappingIid("tap2", IFC_TEST_INSTANCE)), eq( - mapping("tap2", 1).get())); - } - - @Test - public void testModify() throws Exception { - final TapConnectReply t = new TapConnectReply(); - t.swIfIndex = 0; - doReturn(future(t)).when(api).tapConnect(any(TapConnect.class)); - - final TapModifyReply tmodif = new TapModifyReply(); - tmodif.swIfIndex = 0; - doReturn(future(tmodif)).when(api).tapModify(any(TapModify.class)); - - tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext); - - defineMapping(mappingContext, "tap", 1, IFC_TEST_INSTANCE); - tapCustomizer.updateCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), getTapData("tap", "ff:ff:ff:ff:ff:f1"), writeContext); - - verify(api).tapConnect(any(TapConnect.class)); - verify(api).tapModify(any(TapModify.class)); - - verify(mappingContext).put(eq(mappingIid("tap", IFC_TEST_INSTANCE)), eq( - mapping("tap", 0).get())); - } - - @Test - public void testDelete() throws Exception { - final TapConnectReply t = new TapConnectReply(); - t.swIfIndex = 0; - doReturn(future(t)).when(api).tapConnect(any(TapConnect.class)); - - doReturn(future(new TapDeleteReply())).when(api).tapDelete(any(TapDelete.class)); - - tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext); - defineMapping(mappingContext, "tap", 1, IFC_TEST_INSTANCE); - tapCustomizer.deleteCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext); - - verify(api).tapConnect(any(TapConnect.class)); - verify(api).tapDelete(any(TapDelete.class)); - verify(mappingContext).delete(eq(mappingIid("tap", IFC_TEST_INSTANCE))); - } - - private InstanceIdentifier getTapId(final String tap) { - return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(tap)).augmentation( - VppInterfaceAugmentation.class).child(Tap.class); - } - - private Tap getTapData(final String tap, final String mac) { - return new TapBuilder().setTapName(tap).setMac(new PhysAddress(mac)).build(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VhostUserCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VhostUserCustomizerTest.java deleted file mode 100644 index 344b2eb9e..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VhostUserCustomizerTest.java +++ /dev/null @@ -1,205 +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.honeycomb.translate.v3po.interfaces; - -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.Matchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.vpp.util.Ipv4Translator; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -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.rev161214.VhostUserRole; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUserBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.CreateVhostUserIf; -import io.fd.vpp.jvpp.core.dto.CreateVhostUserIfReply; -import io.fd.vpp.jvpp.core.dto.DeleteVhostUserIf; -import io.fd.vpp.jvpp.core.dto.DeleteVhostUserIfReply; -import io.fd.vpp.jvpp.core.dto.ModifyVhostUserIf; -import io.fd.vpp.jvpp.core.dto.ModifyVhostUserIfReply; - -public class VhostUserCustomizerTest extends WriterCustomizerTest implements Ipv4Translator { - - private VhostUserCustomizer customizer; - private static final int IFACE_ID = 1; - private static final String IFACE_NAME = "eth0"; - private static final InstanceIdentifier ID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) - .augmentation(VppInterfaceAugmentation.class).child(VhostUser.class); - - @Override - public void setUp() throws Exception { - InterfaceTypeTestUtils.setupWriteContext(writeContext, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser.class); - customizer = new VhostUserCustomizer(api, new NamingContext("generatedInterfaceName", "test-instance")); - } - - private CreateVhostUserIf verifyCreateVhostUserIfWasInvoked(final VhostUser vhostUser) - throws VppInvocationException { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CreateVhostUserIf.class); - verify(api).createVhostUserIf(argumentCaptor.capture()); - final CreateVhostUserIf actual = argumentCaptor.getValue(); - assertEquals(0, actual.customDevInstance); - - assertEquals(booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer); - assertEquals(0, actual.renumber); - assertEquals(0, actual.useCustomMac); - assertArrayEquals(vhostUser.getSocket().getBytes(), actual.sockFilename); - assertNotNull(actual.macAddress); - return actual; - } - - private ModifyVhostUserIf verifyModifyVhostUserIfWasInvoked(final VhostUser vhostUser, final int swIfIndex) - throws VppInvocationException { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(ModifyVhostUserIf.class); - verify(api).modifyVhostUserIf(argumentCaptor.capture()); - final ModifyVhostUserIf actual = argumentCaptor.getValue(); - assertEquals(0, actual.customDevInstance); - - assertEquals(booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer); - assertEquals(0, actual.renumber); - assertEquals(swIfIndex, actual.swIfIndex); - assertArrayEquals(vhostUser.getSocket().getBytes(), actual.sockFilename); - return actual; - } - - private DeleteVhostUserIf verifyDeleteVhostUserIfWasInvoked(final int swIfIndex) throws VppInvocationException { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(DeleteVhostUserIf.class); - verify(api).deleteVhostUserIf(argumentCaptor.capture()); - final DeleteVhostUserIf actual = argumentCaptor.getValue(); - assertEquals(swIfIndex, actual.swIfIndex); - return actual; - } - - private static VhostUser generateVhostUser(final VhostUserRole role, final String socketName) { - VhostUserBuilder builder = new VhostUserBuilder(); - builder.setRole(role); - builder.setSocket(socketName); - return builder.build(); - } - - @Test - public void testWriteCurrentAttributes() throws Exception { - final VhostUser vhostUser = generateVhostUser(VhostUserRole.Server, "socketName"); - - when(api.createVhostUserIf(any(CreateVhostUserIf.class))).thenReturn(future(new CreateVhostUserIfReply())); - - customizer.writeCurrentAttributes(ID, vhostUser, writeContext); - verifyCreateVhostUserIfWasInvoked(vhostUser); - verify(mappingContext).put(eq(mappingIid(IFACE_NAME, "test-instance")), eq( - mapping(IFACE_NAME, 0).get())); - } - - @Test - public void testWriteCurrentAttributesFailed() throws Exception { - final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName"); - - doReturn(failedFuture()).when(api).createVhostUserIf(any(CreateVhostUserIf.class)); - - try { - customizer.writeCurrentAttributes(ID, vhostUser, writeContext); - } catch (WriteFailedException.CreateFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyCreateVhostUserIfWasInvoked(vhostUser); - verifyZeroInteractions(mappingContext); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testUpdateCurrentAttributes() throws Exception { - final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Client, "socketName0"); - final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName1"); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, "test-instance"); - - when(api.modifyVhostUserIf(any(ModifyVhostUserIf.class))).thenReturn(future(new ModifyVhostUserIfReply())); - - customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext); - verifyModifyVhostUserIfWasInvoked(vhostUserAfter, IFACE_ID); - } - - @Test - public void testUpdateCurrentAttributesFailed() throws Exception { - final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Client, "socketName0"); - final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName1"); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, "test-instance"); - - doReturn(failedFuture()).when(api).modifyVhostUserIf(any(ModifyVhostUserIf.class)); - - try { - customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext); - } catch (WriteFailedException.UpdateFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyModifyVhostUserIfWasInvoked(vhostUserAfter, IFACE_ID); - return; - } - fail("WriteFailedException.UpdateFailedException was expected"); - } - - @Test - public void testDeleteCurrentAttributes() throws Exception { - final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName"); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, "test-instance"); - - when(api.deleteVhostUserIf(any(DeleteVhostUserIf.class))).thenReturn(future(new DeleteVhostUserIfReply())); - - customizer.deleteCurrentAttributes(ID, vhostUser, writeContext); - verifyDeleteVhostUserIfWasInvoked(IFACE_ID); - verify(mappingContext).delete(eq(mappingIid(IFACE_NAME, "test-instance"))); - } - - @Test - public void testDeleteCurrentAttributesFailed() throws Exception { - final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName"); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, "test-instance"); - - doReturn(failedFuture()).when(api).deleteVhostUserIf(any(DeleteVhostUserIf.class)); - - try { - customizer.deleteCurrentAttributes(ID, vhostUser, writeContext); - } catch (WriteFailedException.DeleteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyDeleteVhostUserIfWasInvoked(IFACE_ID); - // Delete from context not invoked if delete from VPP failed - verify(mappingContext, times(0)).delete(eq(mappingIid(IFACE_NAME, "test-instance"))); - verify(mappingContext).read(eq(mappingIid(IFACE_NAME, "test-instance"))); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanCustomizerTest.java deleted file mode 100644 index d2a4f4c9c..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanCustomizerTest.java +++ /dev/null @@ -1,227 +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.honeycomb.translate.v3po.interfaces; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.net.InetAddresses; -import io.fd.honeycomb.translate.v3po.DisabledInterfacesManager; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.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.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanVni; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.VxlanAddDelTunnel; -import io.fd.vpp.jvpp.core.dto.VxlanAddDelTunnelReply; - -public class VxlanCustomizerTest extends WriterCustomizerTest { - - private static final byte ADD_VXLAN = 1; - private static final byte DEL_VXLAN = 0; - - @Mock - private DisabledInterfacesManager disableContext; - - private VxlanCustomizer customizer; - private String ifaceName; - private InstanceIdentifier id; - - @Override - public void setUp() throws Exception { - InterfaceTypeTestUtils.setupWriteContext(writeContext, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel.class); - - customizer = - new VxlanCustomizer(api, new NamingContext("generateInterfaceNAme", "test-instance"), disableContext); - - ifaceName = "eth0"; - id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(ifaceName)) - .augmentation(VppInterfaceAugmentation.class).child(Vxlan.class); - } - - private void whenVxlanAddDelTunnelThenSuccess() { - when(api.vxlanAddDelTunnel(any(VxlanAddDelTunnel.class))).thenReturn(future(new VxlanAddDelTunnelReply())); - } - - private void whenVxlanAddDelTunnelThenFailure() { - doReturn(failedFuture()).when(api).vxlanAddDelTunnel(any(VxlanAddDelTunnel.class)); - } - - private VxlanAddDelTunnel verifyVxlanAddDelTunnelWasInvoked(final Vxlan vxlan) throws VppInvocationException { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(VxlanAddDelTunnel.class); - verify(api).vxlanAddDelTunnel(argumentCaptor.capture()); - final VxlanAddDelTunnel actual = argumentCaptor.getValue(); - assertEquals(0, actual.isIpv6); - assertEquals(-1, actual.decapNextIndex); - assertArrayEquals(InetAddresses.forString(vxlan.getSrc().getIpv4Address().getValue()).getAddress(), - actual.srcAddress); - assertArrayEquals(InetAddresses.forString(vxlan.getDst().getIpv4Address().getValue()).getAddress(), - actual.dstAddress); - assertEquals(vxlan.getEncapVrfId().intValue(), actual.encapVrfId); - assertEquals(vxlan.getVni().getValue().intValue(), actual.vni); - return actual; - } - - private void verifyVxlanAddWasInvoked(final Vxlan vxlan) throws VppInvocationException { - final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan); - assertEquals(ADD_VXLAN, actual.isAdd); - } - - private void verifyVxlanDeleteWasInvoked(final Vxlan vxlan) throws VppInvocationException { - final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan); - assertEquals(DEL_VXLAN, actual.isAdd); - } - - private static Vxlan generateVxlan(long vni) { - final VxlanBuilder builder = new VxlanBuilder(); - builder.setSrc(new IpAddress(new Ipv4Address("192.168.20.10"))); - builder.setDst(new IpAddress(new Ipv4Address("192.168.20.11"))); - builder.setEncapVrfId(Long.valueOf(123)); - builder.setVni(new VxlanVni(Long.valueOf(vni))); - return builder.build(); - } - - private static Vxlan generateVxlan() { - return generateVxlan(Long.valueOf(11)); - } - - @Test - public void testWriteCurrentAttributes() throws Exception { - final Vxlan vxlan = generateVxlan(); - - whenVxlanAddDelTunnelThenSuccess(); - noMappingDefined(mappingContext, ifaceName, "test-instance"); - - customizer.writeCurrentAttributes(id, vxlan, writeContext); - verifyVxlanAddWasInvoked(vxlan); - verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, 0).get())); - } - - @Test - public void testWriteCurrentAttributesWithExistingVxlanPlaceholder() throws Exception { - final Vxlan vxlan = generateVxlan(); - - whenVxlanAddDelTunnelThenSuccess(); - noMappingDefined(mappingContext, ifaceName, "test-instance"); - doReturn(true).when(disableContext).isInterfaceDisabled(0, mappingContext); - - customizer.writeCurrentAttributes(id, vxlan, writeContext); - verifyVxlanAddWasInvoked(vxlan); - verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, 0).get())); - verify(disableContext).removeDisabledInterface(0, mappingContext); - } - - @Test - public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception { - final Vxlan vxlan = generateVxlan(); - final int ifaceId = 0; - - whenVxlanAddDelTunnelThenSuccess(); - defineMapping(mappingContext, ifaceName, ifaceId, "test-instance"); - - customizer.writeCurrentAttributes(id, vxlan, writeContext); - verifyVxlanAddWasInvoked(vxlan); - - // Remove the first mapping before putting in the new one - verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance"))); - verify(mappingContext) - .put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, ifaceId).get())); - } - - @Test - public void testWriteCurrentAttributesFailed() throws Exception { - final Vxlan vxlan = generateVxlan(); - - whenVxlanAddDelTunnelThenFailure(); - - try { - customizer.writeCurrentAttributes(id, vxlan, writeContext); - } catch (WriteFailedException.CreateFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyVxlanAddWasInvoked(vxlan); - // Mapping not stored due to failure - verify(mappingContext, times(0)) - .put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, 0).get())); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testUpdateCurrentAttributes() throws Exception { - try { - customizer.updateCurrentAttributes(id, generateVxlan(10), generateVxlan(11), writeContext); - } catch (WriteFailedException.UpdateFailedException e) { - assertEquals(UnsupportedOperationException.class, e.getCause().getClass()); - return; - } - fail("WriteFailedException.UpdateFailedException was expected"); - } - - @Test - public void testDeleteCurrentAttributes() throws Exception { - final Vxlan vxlan = generateVxlan(); - - whenVxlanAddDelTunnelThenSuccess(); - defineMapping(mappingContext, ifaceName, 1, "test-instance"); - - customizer.deleteCurrentAttributes(id, vxlan, writeContext); - verifyVxlanDeleteWasInvoked(vxlan); - verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance"))); - verify(disableContext).disableInterface(1, mappingContext); - } - - @Test - public void testDeleteCurrentAttributesaFailed() throws Exception { - final Vxlan vxlan = generateVxlan(); - - whenVxlanAddDelTunnelThenFailure(); - defineMapping(mappingContext, ifaceName, 1, "test-instance"); - - try { - customizer.deleteCurrentAttributes(id, vxlan, writeContext); - } catch (WriteFailedException.DeleteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyVxlanDeleteWasInvoked(vxlan); - verify(mappingContext, times(0)).delete(eq(mappingIid(ifaceName, "test-instance"))); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanGpeCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanGpeCustomizerTest.java deleted file mode 100644 index 0792a0e1e..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/VxlanGpeCustomizerTest.java +++ /dev/null @@ -1,218 +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.honeycomb.translate.v3po.interfaces; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.net.InetAddresses; -import io.fd.honeycomb.translate.v3po.DisabledInterfacesManager; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.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.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeNextProtocol; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeVni; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpeBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.VxlanGpeAddDelTunnel; -import io.fd.vpp.jvpp.core.dto.VxlanGpeAddDelTunnelReply; - -public class VxlanGpeCustomizerTest extends WriterCustomizerTest { - - private static final byte ADD_VXLAN_GPE = 1; - private static final byte DEL_VXLAN_GPE = 0; - - @Mock - private DisabledInterfacesManager interfaceDisableContext; - - private VxlanGpeCustomizer customizer; - private String ifaceName; - private InstanceIdentifier id; - - @Override - public void setUp() throws Exception { - InterfaceTypeTestUtils.setupWriteContext(writeContext, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel.class); - NamingContext namingContext = new NamingContext("generateInterfaceName", "test-instance"); - customizer = new VxlanGpeCustomizer(api, namingContext, interfaceDisableContext); - - ifaceName = "elth0"; - id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(ifaceName)) - .augmentation(VppInterfaceAugmentation.class).child(VxlanGpe.class); - } - - private void whenVxlanGpeAddDelTunnelThenSuccess() { - when(api.vxlanGpeAddDelTunnel(any(VxlanGpeAddDelTunnel.class))) - .thenReturn(future(new VxlanGpeAddDelTunnelReply())); - } - - private void whenVxlanGpeAddDelTunnelThenFailure() { - doReturn(failedFuture()).when(api).vxlanGpeAddDelTunnel(any(VxlanGpeAddDelTunnel.class)); - } - - private VxlanGpeAddDelTunnel verifyVxlanGpeAddDelTunnelWasInvoked(final VxlanGpe vxlanGpe) - throws VppBaseCallException { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(VxlanGpeAddDelTunnel.class); - verify(api).vxlanGpeAddDelTunnel(argumentCaptor.capture()); - final VxlanGpeAddDelTunnel actual = argumentCaptor.getValue(); - assertEquals(0, actual.isIpv6); - assertArrayEquals(InetAddresses.forString(vxlanGpe.getLocal().getIpv4Address().getValue()).getAddress(), - actual.local); - assertArrayEquals(InetAddresses.forString(vxlanGpe.getRemote().getIpv4Address().getValue()).getAddress(), - actual.remote); - assertEquals(vxlanGpe.getVni().getValue().intValue(), actual.vni); - assertEquals(vxlanGpe.getNextProtocol().getIntValue(), actual.protocol); - assertEquals(vxlanGpe.getEncapVrfId().intValue(), actual.encapVrfId); - assertEquals(vxlanGpe.getDecapVrfId().intValue(), actual.decapVrfId); - return actual; - } - - private void verifyVxlanGpeAddWasInvoked(final VxlanGpe vxlanGpe) throws VppBaseCallException { - final VxlanGpeAddDelTunnel actual = verifyVxlanGpeAddDelTunnelWasInvoked(vxlanGpe); - assertEquals(ADD_VXLAN_GPE, actual.isAdd); - } - - private void verifyVxlanGpeDeleteWasInvoked(final VxlanGpe vxlanGpe) throws VppBaseCallException { - final VxlanGpeAddDelTunnel actual = verifyVxlanGpeAddDelTunnelWasInvoked(vxlanGpe); - assertEquals(DEL_VXLAN_GPE, actual.isAdd); - } - - private static VxlanGpe generateVxlanGpe(long vni) { - final VxlanGpeBuilder builder = new VxlanGpeBuilder(); - builder.setLocal(new IpAddress(new Ipv4Address("192.168.20.10"))); - builder.setRemote(new IpAddress(new Ipv4Address("192.168.20.11"))); - builder.setVni(new VxlanGpeVni(Long.valueOf(vni))); - builder.setNextProtocol(VxlanGpeNextProtocol.forValue(1)); - builder.setEncapVrfId(Long.valueOf(123)); - builder.setDecapVrfId(Long.valueOf(456)); - return builder.build(); - } - - private static VxlanGpe generateVxlanGpe() { - return generateVxlanGpe(Long.valueOf(11)); - } - - @Test - public void testWriteCurrentAttributes() throws Exception { - final VxlanGpe vxlanGpe = generateVxlanGpe(); - - whenVxlanGpeAddDelTunnelThenSuccess(); - noMappingDefined(mappingContext, ifaceName, "test-instance"); - - customizer.writeCurrentAttributes(id, vxlanGpe, writeContext); - verifyVxlanGpeAddWasInvoked(vxlanGpe); - verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), eq( - mapping(ifaceName, 0).get())); - } - - @Test - public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception { - final VxlanGpe vxlanGpe = generateVxlanGpe(); - final int ifaceId = 0; - - whenVxlanGpeAddDelTunnelThenSuccess(); - defineMapping(mappingContext, ifaceName, ifaceId, "test-instance"); - - customizer.writeCurrentAttributes(id, vxlanGpe, writeContext); - verifyVxlanGpeAddWasInvoked(vxlanGpe); - - // Remove the first mapping before putting in the new one - verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance"))); - verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), - eq(mapping(ifaceName, ifaceId).get())); - } - - @Test - public void testWriteCurrentAttributesFailed() throws Exception { - final VxlanGpe vxlanGpe = generateVxlanGpe(); - - whenVxlanGpeAddDelTunnelThenFailure(); - - try { - customizer.writeCurrentAttributes(id, vxlanGpe, writeContext); - } catch (WriteFailedException.CreateFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyVxlanGpeAddWasInvoked(vxlanGpe); - // Mapping not stored due to failure - verify(mappingContext, times(0)) - .put(eq(mappingIid(ifaceName, "test-instance")), eq( - mapping(ifaceName, 0).get())); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testUpdateCurrentAttributes() throws Exception { - try { - customizer.updateCurrentAttributes(id, generateVxlanGpe(10), generateVxlanGpe(11), writeContext); - } catch (WriteFailedException.UpdateFailedException e) { - assertEquals(UnsupportedOperationException.class, e.getCause().getClass()); - return; - } - fail("WriteFailedException.UpdateFailedException was expected"); - } - - @Test - public void testDeleteCurrentAttributes() throws Exception { - final VxlanGpe vxlanGpe = generateVxlanGpe(); - - whenVxlanGpeAddDelTunnelThenSuccess(); - defineMapping(mappingContext, ifaceName, 1, "test-instance"); - - customizer.deleteCurrentAttributes(id, vxlanGpe, writeContext); - verifyVxlanGpeDeleteWasInvoked(vxlanGpe); - verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance"))); - } - - @Test - public void testDeleteCurrentAttributesaFailed() throws Exception { - final VxlanGpe vxlanGpe = generateVxlanGpe(); - - whenVxlanGpeAddDelTunnelThenFailure(); - defineMapping(mappingContext, ifaceName, 1, "test-instance"); - - try { - customizer.deleteCurrentAttributes(id, vxlanGpe, writeContext); - } catch (WriteFailedException.DeleteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyVxlanGpeDeleteWasInvoked(vxlanGpe); - verify(mappingContext, times(0)).delete(eq(mappingIid(ifaceName, "test-instance"))); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AclWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AclWriterTest.java deleted file mode 100644 index d2ace4a10..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AclWriterTest.java +++ /dev/null @@ -1,103 +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.honeycomb.translate.v3po.interfaces.acl; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import java.util.Collections; -import java.util.List; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; -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.InterfacesBuilder; -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.InterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class AclWriterTest extends WriterCustomizerTest { - - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = EthAcl.class; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey(ACL_NAME, ACL_TYPE)); - - @Mock - private Acl acl; - private IetfAclWriter customizer; - - @Override - public void setUp() { - customizer = new IetfAclWriter(); - when(acl.getAclName()).thenReturn(ACL_NAME); - doReturn(ACL_TYPE).when(acl).getAclType(); - } - - private void defineInterfacesContext(final List interfaces) { - when(writeContext.readAfter(InstanceIdentifier.create(Interfaces.class))).thenReturn(Optional.of( - new InterfacesBuilder().setInterface(interfaces).build() - )); - } - - @Test - public void testWrite() throws Exception { - customizer.writeCurrentAttributes(IID, acl, writeContext); - } - - @Test - public void testUpdate() throws WriteFailedException { - defineInterfacesContext(Collections.emptyList()); - customizer.updateCurrentAttributes(IID, acl, acl, writeContext); - } - - @Test - public void testDelete() throws WriteFailedException { - defineInterfacesContext(Collections.emptyList()); - customizer.deleteCurrentAttributes(IID, acl, writeContext); - } - - @Test(expected = WriteFailedException.class) - public void testDeleteFailed() throws WriteFailedException { - final Interface iface = new InterfaceBuilder().addAugmentation(VppInterfaceAugmentation.class, - new VppInterfaceAugmentationBuilder().setIetfAcl( - new IetfAclBuilder().setIngress( - new IngressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder().setName(ACL_NAME).setType(ACL_TYPE).build()) - ).build() - ).build() - ).build() - ).build() - ).build(); - defineInterfacesContext(Collections.singletonList(iface)); - customizer.deleteCurrentAttributes(IID, acl, writeContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceEthWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceEthWriterTest.java deleted file mode 100644 index 3a50b7673..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceEthWriterTest.java +++ /dev/null @@ -1,94 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import org.junit.Before; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEthBuilder; -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.vpp.acl.rev161214.InterfaceMode; - -public class AceEthWriterTest { - - private AceEthWriter writer; - private PacketHandling action; - private AceEth aceEth; - - @Before - public void setUp() { - initMocks(this); - writer = new AceEthWriter(); - action = new DenyBuilder().setDeny(true).build(); - aceEth = new AceEthBuilder() - .setDestinationMacAddress(new MacAddress("11:22:33:44:55:66")) - .setDestinationMacAddressMask(new MacAddress("ff:ff:ff:ff:ff:ff")) - .setSourceMacAddress(new MacAddress("aa:bb:cc:dd:ee:ff")) - .setSourceMacAddressMask(new MacAddress("ff:ff:ff:00:00:00")) - .build(); - } - - @Test - public void testCreateTable() { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = writer.createTable(aceEth, InterfaceMode.L2, nextTableIndex, 0); - - assertEquals(1, request.isAdd); - assertEquals(-1, request.tableIndex); - assertEquals(1, request.nbuckets); - assertEquals(nextTableIndex, request.nextTableIndex); - assertEquals(0, request.skipNVectors); - assertEquals(AceEthWriter.MATCH_N_VECTORS, request.matchNVectors); - assertEquals(AceEthWriter.TABLE_MEM_SIZE, request.memorySize); - - byte[] expectedMask = new byte[] { - // destination MAC: - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - // source MAC: - (byte) 0xff, (byte) 0xff, (byte) 0xff, 0, 0, 0, - 0, 0, 0, 0 - }; - assertArrayEquals(expectedMask, request.mask); - } - - @Test - public void testCreateClassifySession() { - final int tableIndex = 123; - final ClassifyAddDelSession request = writer.createSession(action, aceEth, InterfaceMode.L2, tableIndex, 0).get(0); - - assertEquals(1, request.isAdd); - assertEquals(tableIndex, request.tableIndex); - assertEquals(0, request.hitNextIndex); - - byte[] expectedMatch = new byte[] { - // destination MAC: - (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - // source MAC: - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, - 0, 0, 0, 0 - }; - assertArrayEquals(expectedMatch, request.match); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp4WriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp4WriterTest.java deleted file mode 100644 index f3a9d0f87..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp4WriterTest.java +++ /dev/null @@ -1,189 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTranslator.VLAN_TAG_LEN; -import static org.junit.Assert.assertEquals; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import org.junit.Before; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; - -public class AceIp4WriterTest { - - private AceIp4Writer writer; - private PacketHandling action; - private AceIp aceIp; - - @Before - public void setUp() throws Exception { - initMocks(this); - writer = new AceIp4Writer(); - action = new DenyBuilder().setDeny(true).build(); - aceIp = new AceIpBuilder() - .setProtocol((short) 132) - .setDscp(new Dscp((short) 11)) - .setAceIpVersion(new AceIpv4Builder() - .setSourceIpv4Network(new Ipv4Prefix("1.2.3.4/32")) - .setDestinationIpv4Network(new Ipv4Prefix("1.2.4.5/24")) - .build()) - .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) - .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) - .build(); - } - - private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex, - final int vlanTags, final boolean isL2) { - assertEquals(1, request.isAdd); - assertEquals(-1, request.tableIndex); - assertEquals(1, request.nbuckets); - assertEquals(nextTableIndex, request.nextTableIndex); - assertEquals(0, request.skipNVectors); - assertEquals(AceIp4Writer.MATCH_N_VECTORS, request.matchNVectors); - assertEquals(AceIp4Writer.TABLE_MEM_SIZE, request.memorySize); - - byte[] expectedMask = new byte[] { - // L2: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // dscp: - (byte) 0x00, (byte) 0xfc, - // protocol: - 0, 0, 0, 0, 0, 0, 0, (byte) 0xff, 0, 0, - // source address: - -1, -1, -1, -1, - // destination address: - -1, -1, -1, 0, - // source and destination port: - -1, -1, -1, -1, - // padding: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - if (isL2) { - expectedMask[12] = (byte) 0xff; - expectedMask[13] = (byte) 0xff; - } - AceIpWriterTestUtils - .assertArrayEqualsWithOffset(expectedMask, expectedMask.length, request.mask, vlanTags * VLAN_TAG_LEN); - - } - - private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex, - final int vlanTags, final boolean isL2) { - assertEquals(1, request.isAdd); - assertEquals(tableIndex, request.tableIndex); - assertEquals(0, request.hitNextIndex); - - byte[] expectedMatch = new byte[] { - // L2: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // dscp: - 0, (byte) 0x2c, - // protocol (132): - 0, 0, 0, 0, 0, 0, 0, (byte) 132, 0, 0, - // source address: - 1, 2, 3, 4, - // destination address: - 1, 2, 4, 0, - // source and destination port: - 0x11, 0x11, 0x22, 0x22, - // padding: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - if (isL2) { - expectedMatch[12] = (byte) 0x08; - expectedMatch[13] = (byte) 0x00; - } - AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMatch, expectedMatch.length, request.match, vlanTags * VLAN_TAG_LEN); - - } - - @Test - public void testCreateTable() throws Exception { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, 0); - verifyTableRequest(request, nextTableIndex, 0, false); - } - - @Test - public void testCreateTableForL2Interface() throws Exception { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L2, nextTableIndex, 0); - verifyTableRequest(request, nextTableIndex, 0, true); - } - - @Test - public void testCreateTable1VlanTag() throws Exception { - final int nextTableIndex = 42; - final int vlanTags = 1; - final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); - verifyTableRequest(request, nextTableIndex, vlanTags, false); - } - - @Test - public void testCreateTable2VlanTags() throws Exception { - final int nextTableIndex = 42; - final int vlanTags = 2; - final ClassifyAddDelTable request = writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); - verifyTableRequest(request, nextTableIndex, vlanTags, false); - } - - @Test - public void testCreateClassifySession() throws Exception { - final int tableIndex = 123; - final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, 0).get(0); - verifySessionRequest(request, tableIndex, 0, false); - } - - @Test - public void testCreateClassifySessionForL2Interface() throws Exception { - final int tableIndex = 123; - final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L2, tableIndex, 0).get(0); - verifySessionRequest(request, tableIndex, 0, true); - } - - @Test - public void testCreateClassifySession1VlanTag() throws Exception { - final int tableIndex = 123; - final int vlanTags = 1; - final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); - verifySessionRequest(request, tableIndex, vlanTags, false); - } - - @Test - public void testCreateClassifySession2VlanTags() throws Exception { - final int tableIndex = 123; - final int vlanTags = 2; - final ClassifyAddDelSession request = writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); - - verifySessionRequest(request, tableIndex, vlanTags, false); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp6WriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp6WriterTest.java deleted file mode 100644 index 382d8840e..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIp6WriterTest.java +++ /dev/null @@ -1,201 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTranslator.VLAN_TAG_LEN; -import static org.junit.Assert.assertEquals; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import org.junit.Before; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6FlowLabel; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; - -public class AceIp6WriterTest { - - private AceIp6Writer writer; - private PacketHandling action; - private AceIp aceIp; - - @Before - public void setUp() { - initMocks(this); - writer = new AceIp6Writer(); - action = new DenyBuilder().setDeny(true).build(); - aceIp = new AceIpBuilder() - .setProtocol((short) 132) - .setDscp(new Dscp((short) 11)) - .setAceIpVersion(new AceIpv6Builder() - .setFlowLabel(new Ipv6FlowLabel(123L)) - .setSourceIpv6Network(new Ipv6Prefix("2001:db8:85a3:8d3:1319:8a2e:370:7348/128")) - .setDestinationIpv6Network(new Ipv6Prefix("fe80:1234:5678:abcd:ef01::/64")) - .build()) - .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) - .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) - .build(); - } - - - private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex, - final int vlanTags, final boolean isL2) { - assertEquals(1, request.isAdd); - assertEquals(-1, request.tableIndex); - assertEquals(1, request.nbuckets); - assertEquals(nextTableIndex, request.nextTableIndex); - assertEquals(0, request.skipNVectors); - assertEquals(vlanTags == 2 ? 5 : 4, request.matchNVectors); - assertEquals(AceIp6Writer.TABLE_MEM_SIZE, request.memorySize); - - byte[] expectedMask = new byte[] { - // L2: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // dscp, flow: - (byte) 0x0f, (byte) 0xcf, (byte) 0xff, (byte) 0xff, - // protocol: - 0, 0, (byte) 0xff, 0, - // source address: - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - // destination address: - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - 0, 0, 0, 0, 0, 0, 0, 0, - // source and destination port: - -1, -1, -1, -1, - // padding to multiple of 16B: - 0, 0, 0, 0, 0, 0 - }; - - if (isL2) { - expectedMask[12] = (byte) 0xff; - expectedMask[13] = (byte) 0xff; - } - AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMask, vlanTags == 2 ? 80 : 64, request.mask, vlanTags * VLAN_TAG_LEN); - } - - private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex, - final int vlanTags, final boolean isL2) { - assertEquals(1, request.isAdd); - assertEquals(tableIndex, request.tableIndex); - assertEquals(0, request.hitNextIndex); - - byte[] expectedMatch = new byte[] { - // L2: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // dscp(11), flow(123): - (byte) 0x02, (byte) 0xc0, (byte) 0x00, (byte) 0x7b, - // protocol (132): - 0, 0, (byte) 132, 0, - // source address: - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, (byte) 0x85, (byte) 0xa3, (byte) 0x08, (byte) 0xd3, - (byte) 0x13, (byte) 0x19, (byte) 0x8a, (byte) 0x2e, (byte) 0x03, (byte) 0x70, (byte) 0x73, (byte) 0x48, - // destination address: - (byte) 0xfe, (byte) 0x80, (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0xab, (byte) 0xcd, - 0, 0, 0, 0, 0, 0, 0, 0, - // source and destination port: - 0x11, 0x11, 0x22, 0x22, - // padding to multiple of 16B: - 0, 0, 0, 0, 0, 0 - }; - - if (isL2) { - expectedMatch[12] = (byte) 0x86; - expectedMatch[13] = (byte) 0xdd; - } - AceIpWriterTestUtils.assertArrayEqualsWithOffset(expectedMatch, vlanTags == 2 ? 80 : 64, request.match, vlanTags * VLAN_TAG_LEN); - - } - - @Test - public void testCreateTable() { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = - writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, 0); - verifyTableRequest(request, nextTableIndex, 0, false); - } - - @Test - public void testCreateTableForL2Interface() { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = - writer.createTable(aceIp, InterfaceMode.L2, nextTableIndex, 0); - verifyTableRequest(request, nextTableIndex, 0, true); - } - - @Test - public void testCreateTable1VlanTag() { - final int nextTableIndex = 42; - final int vlanTags = 1; - final ClassifyAddDelTable request = - writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); - verifyTableRequest(request, nextTableIndex, vlanTags, false); - } - - @Test - public void testCreateTable2VlanTags() { - final int nextTableIndex = 42; - final int vlanTags = 2; - final ClassifyAddDelTable request = - writer.createTable(aceIp, InterfaceMode.L3, nextTableIndex, vlanTags); - verifyTableRequest(request, nextTableIndex, vlanTags, false); - } - - @Test - public void testCreateClassifySession() { - final int tableIndex = 123; - final ClassifyAddDelSession request = - writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, 0).get(0); - verifySessionRequest(request, tableIndex, 0, false); - } - - @Test - public void testCreateClassifySessionForL2Interface() { - final int tableIndex = 123; - final ClassifyAddDelSession request = - writer.createSession(action, aceIp, InterfaceMode.L2, tableIndex, 0).get(0); - verifySessionRequest(request, tableIndex, 0, true); - } - - @Test - public void testCreateClassifySession1VlanTag() { - final int tableIndex = 123; - final int vlanTags = 1; - final ClassifyAddDelSession request = - writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); - verifySessionRequest(request, tableIndex, vlanTags, false); - } - - @Test - public void testCreateClassifySession2VlanTags() { - final int tableIndex = 123; - final int vlanTags = 2; - final ClassifyAddDelSession request = - writer.createSession(action, aceIp, InterfaceMode.L3, tableIndex, vlanTags).get(0); - verifySessionRequest(request, tableIndex, vlanTags, false); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java deleted file mode 100644 index d224a067f..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpAndEthWriterTest.java +++ /dev/null @@ -1,123 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import org.junit.Before; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder; -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.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEthBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv4Builder; - -public class AceIpAndEthWriterTest { - - private AceIpAndEthWriter writer; - private PacketHandling action; - private AceIpAndEth ace; - - @Before - public void setUp() { - initMocks(this); - writer = new AceIpAndEthWriter(); - action = new DenyBuilder().setDeny(true).build(); - ace = new AceIpAndEthBuilder() - .setDestinationMacAddress(new MacAddress("11:22:33:44:55:66")) - .setSourceMacAddress(new MacAddress("aa:bb:cc:dd:ee:ff")) - .setAceIpVersion(new AceIpv4Builder() - .setSourceIpv4Network(new Ipv4Prefix("1.2.3.4/32")).build()) - .setSourcePortRange(new SourcePortRangeBuilder().setLowerPort(new PortNumber(0x1111)).build()) - .setDestinationPortRange(new DestinationPortRangeBuilder().setLowerPort(new PortNumber(0x2222)).build()) - .build(); - } - - @Test - public void testCreateTable() { - final int nextTableIndex = 42; - final ClassifyAddDelTable request = writer.createTable(ace, InterfaceMode.L2, nextTableIndex, 0); - - assertEquals(1, request.isAdd); - assertEquals(-1, request.tableIndex); - assertEquals(1, request.nbuckets); - assertEquals(nextTableIndex, request.nextTableIndex); - assertEquals(0, request.skipNVectors); - assertEquals(3, request.matchNVectors); - assertEquals(AceEthWriter.TABLE_MEM_SIZE, request.memorySize); - - byte[] expectedMask = new byte[] { - // destination MAC: - -1, -1, -1, -1, -1, -1, - // source MAC: - -1, -1, -1, -1, -1, -1, - // ether type: - -1, -1, - // IP header - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // source address: - -1, -1, -1, -1, - // destination address: - 0, 0, 0, 0, - // source and destination port: - -1, -1, -1, -1, - // padding: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - assertArrayEquals(expectedMask, request.mask); - } - - @Test - public void testCreateClassifySession() { - final int tableIndex = 123; - final ClassifyAddDelSession request = writer.createSession(action, ace, InterfaceMode.L2, tableIndex, 0).get(0); - - assertEquals(1, request.isAdd); - assertEquals(tableIndex, request.tableIndex); - assertEquals(0, request.hitNextIndex); - - byte[] expectedMatch = new byte[] { - // destination MAC: - (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - // source MAC: - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, - // ether type (IP4): - 0x08, 0, - // IP header - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // source address: - 1, 2, 3, 4, - // destination address: - 0, 0, 0, 0, - // source and destination port: - 0x11, 0x11, 0x22, 0x22, - // padding: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - assertArrayEquals(expectedMatch, request.match); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpWriterTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpWriterTestUtils.java deleted file mode 100644 index 59e22a87b..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AceIpWriterTestUtils.java +++ /dev/null @@ -1,34 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static org.junit.Assert.assertArrayEquals; - -final class AceIpWriterTestUtils { - - private AceIpWriterTestUtils() { - throw new UnsupportedOperationException("This utility class cannot be instantiated"); - } - - protected static void assertArrayEqualsWithOffset(final byte[] baseExpected, final int expectedLength, final byte[] actual, - final int offset) { - byte[] expected = new byte[expectedLength]; - System.arraycopy(baseExpected, 0, expected, offset, Math.min(baseExpected.length, expectedLength-offset)); - - assertArrayEquals(expected, actual); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java deleted file mode 100644 index 490e26b2b..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImplTest.java +++ /dev/null @@ -1,62 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static org.mockito.Mockito.verify; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.honeycomb.translate.MappingContext; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; - -public class AclTableContextManagerImplTest { - - private AclTableContextManagerImpl ctx; - @Mock - private MappingContext mappingContext; - private static final int INDEX = 42; - - @Before - public void setUp() throws Exception { - initMocks(this); - ctx = new AclTableContextManagerImpl(MappingTable.Direction.Ingress); - } - - @Test - public void testAddEntry() throws Exception { - final MappingEntry entry = - new MappingEntryBuilder().setL2TableId(1).setIp4TableId(2).setIp6TableId(3).setIndex(INDEX).build(); - ctx.addEntry(entry, mappingContext); - verify(mappingContext).put(ctx.getId(INDEX), entry); - } - - @Test - public void testRemoveEntry() throws Exception { - ctx.removeEntry(INDEX, mappingContext); - verify(mappingContext).delete(ctx.getId(INDEX)); - } - - @Test - public void testReadEntry() throws Exception { - ctx.getEntry(INDEX, mappingContext); - verify(mappingContext).read(ctx.getId(INDEX)); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/PortPairTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/PortPairTest.java deleted file mode 100644 index 2127fb0fa..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/PortPairTest.java +++ /dev/null @@ -1,114 +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.honeycomb.translate.v3po.interfaces.acl.common; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.hasSize; - -import java.util.List; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder; - -public class PortPairTest { - - @Test - public void testSingleSrc() { - final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(123)).build(); - final List portPairs = PortPair.fromRange(src, null); - assertThat(portPairs, hasSize(1)); - assertThat(portPairs, contains(new PortPair(123, null))); - } - - @Test - public void testSrcRange() { - final SourcePortRange src = new SourcePortRangeBuilder() - .setLowerPort(new PortNumber(123)) - .setUpperPort(new PortNumber(125)).build(); - final List portPairs = PortPair.fromRange(src, null); - assertThat(portPairs, hasSize(3)); - assertThat(portPairs, contains(new PortPair(123, null), new PortPair(124, null), new PortPair(125, null))); - } - - @Test - public void testSrcRangeWithDst() { - final SourcePortRange src = new SourcePortRangeBuilder() - .setLowerPort(new PortNumber(123)) - .setUpperPort(new PortNumber(125)).build(); - final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(111)).build(); - final List portPairs = PortPair.fromRange(src, dst); - assertThat(portPairs, hasSize(3)); - assertThat(portPairs, contains(new PortPair(123, 111), new PortPair(124, 111), new PortPair(125, 111))); - } - - @Test - public void testSingleDst() { - final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(123)).build(); - final List portPairs = PortPair.fromRange(null, dst); - assertThat(portPairs, hasSize(1)); - assertThat(portPairs, contains(new PortPair(null, 123))); - } - - @Test - public void testDstRange() { - final DestinationPortRange dst = new DestinationPortRangeBuilder() - .setLowerPort(new PortNumber(10)) - .setUpperPort(new PortNumber(11)).build(); - final List portPairs = PortPair.fromRange(null, dst); - assertThat(portPairs, hasSize(2)); - assertThat(portPairs, contains(new PortPair(null, 10), new PortPair(null, 11))); - } - - @Test - public void testDstRangeWithSrc() { - final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(111)).build(); - final DestinationPortRange dst = new DestinationPortRangeBuilder() - .setLowerPort(new PortNumber(10)) - .setUpperPort(new PortNumber(11)).build(); - final List portPairs = PortPair.fromRange(src, dst); - assertThat(portPairs, hasSize(2)); - assertThat(portPairs, contains(new PortPair(111, 10), new PortPair(111, 11))); - } - - @Test - public void testSinglePair() { - final SourcePortRange src = new SourcePortRangeBuilder().setLowerPort(new PortNumber(123)).build(); - final DestinationPortRange dst = new DestinationPortRangeBuilder().setLowerPort(new PortNumber(321)).build(); - final List portPairs = PortPair.fromRange(src, dst); - assertThat(portPairs, hasSize(1)); - assertThat(portPairs, contains(new PortPair(123, 321))); - } - - @Test - public void testCartesianProduct() { - final SourcePortRange src = new SourcePortRangeBuilder() - .setLowerPort(new PortNumber(1)) - .setUpperPort(new PortNumber(2)).build(); - final DestinationPortRange dst = new DestinationPortRangeBuilder() - .setLowerPort(new PortNumber(1)) - .setUpperPort(new PortNumber(3)).build(); - final List portPairs = PortPair.fromRange(src, dst); - assertThat(portPairs, hasSize(6)); - assertThat(portPairs, - contains(new PortPair(1, 1), new PortPair(1, 2), new PortPair(1, 3), new PortPair(2, 1), new PortPair(2, 2), - new PortPair(2, 3))); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java deleted file mode 100644 index e1aa0b85e..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriterTest.java +++ /dev/null @@ -1,151 +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.honeycomb.translate.v3po.interfaces.acl.egress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManager; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2Tables; -import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2TablesReply; -import java.util.Collections; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.AceBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.ActionsBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.MatchesBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.PermitBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.EgressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class EgressIetfAclWriterTest extends WriterCustomizerTest { - - private static final int IF_INDEX = 1; - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = EthAcl.class; - - private EgressIetfAclWriter writer; - @Mock - private AclTableContextManager aclCtx; - @Mock - private InstanceIdentifier id; - - @Override - protected void setUp() throws Exception { - writer = new EgressIetfAclWriter(api, aclCtx); - } - - private static ClassifyAddDelTable classifyAddDelTable(final int tableIndex) { - final ClassifyAddDelTable reply = new ClassifyAddDelTable(); - reply.tableIndex = tableIndex; - return reply; - } - - private ClassifySetInterfaceL2Tables classifySetInterfaceL2TablesRequest() { - final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); - request.isInput = 0; - request.ip4TableIndex = -1; - request.ip6TableIndex = -1; - request.otherTableIndex = -1; - request.swIfIndex = IF_INDEX; - return request; - } - - @Test - public void testDeleteAcl() throws Exception { - when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); - when(api.classifySetInterfaceL2Tables(any())).thenReturn(future(new ClassifySetInterfaceL2TablesReply())); - when(aclCtx.getEntry(IF_INDEX, mappingContext)).thenReturn(Optional.of( - new MappingEntryBuilder() - .setIndex(IF_INDEX) - .setL2TableId(1) - .setIp4TableId(2) - .setIp6TableId(3) - .build())); - - writer.deleteAcl(id, IF_INDEX, mappingContext); - - verify(api).classifySetInterfaceL2Tables(classifySetInterfaceL2TablesRequest()); - verify(api).classifyAddDelTable(classifyAddDelTable(1)); - verify(api).classifyAddDelTable(classifyAddDelTable(2)); - verify(api).classifyAddDelTable(classifyAddDelTable(3)); - verify(aclCtx).removeEntry(IF_INDEX, mappingContext); - } - - @Test - public void testWrite() throws Exception { - when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); - when(api.classifyAddDelSession(any())).thenReturn(future(new ClassifyAddDelSessionReply())); - when(api.classifySetInterfaceL2Tables(any())).thenReturn(future(new ClassifySetInterfaceL2TablesReply())); - - final Egress - acl = new EgressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).setMode(InterfaceMode.L2).build() - ).build(); - - final AccessLists accessLists = acl.getAccessLists(); - - when(writeContext.readAfter(any())).thenReturn(Optional.of( - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() - .setAccessListEntries( - new AccessListEntriesBuilder().setAce(Collections.singletonList(new AceBuilder() - .setMatches(new MatchesBuilder().setAceType( - new AceIpBuilder() - .setAceIpVersion(new AceIpv4Builder().build()) - .setProtocol((short) 1) - .build() - ).build()) - .setActions(new ActionsBuilder().setPacketHandling(new PermitBuilder().build()).build()) - .build())).build() - ).build() - - )); - - writer.write(id, IF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, mappingContext); - - final ClassifySetInterfaceL2Tables request = new ClassifySetInterfaceL2Tables(); - request.isInput = 0; - request.swIfIndex = IF_INDEX; - request.otherTableIndex = -1; - request.ip4TableIndex = 0; - request.ip6TableIndex = -1; - verify(api).classifySetInterfaceL2Tables(request); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java deleted file mode 100644 index 2be2212ff..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizerTest.java +++ /dev/null @@ -1,114 +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.honeycomb.translate.v3po.interfaces.acl.egress; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.IetfAclWriter; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import java.util.Collections; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -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.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.EgressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.MixedAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class IetfAclCustomizerTest extends WriterCustomizerTest { - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - VppInterfaceAugmentation.class).child(IetfAcl.class).child(Egress.class); - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = MixedAcl.class; - - @Mock - private IetfAclWriter aclWriter; - private IetfAclCustomizer customizer; - - @Override - protected void setUp() { - customizer = new IetfAclCustomizer(aclWriter, new NamingContext("prefix", IFC_TEST_INSTANCE)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - } - - private static Egress acl(final InterfaceMode mode) { - return new EgressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).setMode(mode) - .build() - ).build(); - } - - private void verifyWrite(final AccessLists accessLists) throws WriteFailedException { - verify(aclWriter) - .write(IID, IF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, mappingContext); - } - - private void verifyDelete() throws WriteFailedException { - verify(aclWriter).deleteAcl(IID, IF_INDEX, mappingContext); - } - - @Test - public void testWriteL3() throws Exception { - customizer.writeCurrentAttributes(IID, acl(InterfaceMode.L3), writeContext); - verifyZeroInteractions(aclWriter); - } - - @Test - public void testWriteL2() throws Exception { - final Egress acl = acl(InterfaceMode.L2); - customizer.writeCurrentAttributes(IID, acl, writeContext); - verifyWrite(acl.getAccessLists()); - } - - @Test - public void testUpdate() throws Exception { - final Egress aclBefore = acl(InterfaceMode.L3); - final Egress aclAfter = acl(InterfaceMode.L2); - customizer.updateCurrentAttributes(IID, aclBefore, aclAfter, writeContext); - verifyDelete(); - verifyWrite(aclAfter.getAccessLists()); - } - - @Test - public void testDelete() throws Exception { - final Egress acl = acl(InterfaceMode.L2); - customizer.deleteCurrentAttributes(IID, acl, writeContext); - verifyDelete(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java deleted file mode 100644 index abefa2465..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizerTest.java +++ /dev/null @@ -1,130 +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.honeycomb.translate.v3po.interfaces.acl.egress; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.IetfAclWriter; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import java.util.Collections; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -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.vpp.acl.rev161214.InterfaceMode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.MixedAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Egress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.EgressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceIetfAclCustomizerTest extends WriterCustomizerTest { - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUBIF_NAME = "local0.0"; - private static final int SUBIF_INDEX = 11; - private static final long SUBIF_ID = 0; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(IetfAcl.class).child(Egress.class); - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = MixedAcl.class; - - @Mock - private IetfAclWriter aclWriter; - private SubInterfaceIetfAclCustomizer customizer; - - @Override - protected void setUp() { - customizer = new SubInterfaceIetfAclCustomizer(aclWriter, new NamingContext("prefix", IFC_TEST_INSTANCE)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); - - - when(writeContext.readAfter(IID.firstIdentifierOf(SubInterface.class))).thenReturn(Optional.of( - new SubInterfaceBuilder().build() - )); - } - - private static Egress acl(final InterfaceMode mode) { - return new EgressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).setMode(mode) - .build() - ).build(); - } - - private void verifyWrite(final AccessLists accessLists) throws WriteFailedException { - verify(aclWriter) - .write(IID, SUBIF_INDEX, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, 0, mappingContext); - } - - private void verifyDelete() throws WriteFailedException { - verify(aclWriter).deleteAcl(IID, SUBIF_INDEX, mappingContext); - } - - @Test - public void testWriteL3() throws Exception { - customizer.writeCurrentAttributes(IID, acl(InterfaceMode.L3), writeContext); - verifyZeroInteractions(aclWriter); - } - - @Test - public void testWriteL2() throws Exception { - final Egress acl = acl(InterfaceMode.L2); - customizer.writeCurrentAttributes(IID, acl, writeContext); - verifyWrite(acl.getAccessLists()); - } - - @Test - public void testUpdate() throws Exception { - final Egress aclBefore = acl(InterfaceMode.L3); - final Egress aclAfter = acl(InterfaceMode.L2); - customizer.updateCurrentAttributes(IID, aclBefore, aclAfter, writeContext); - verifyDelete(); - verifyWrite(aclAfter.getAccessLists()); - } - - @Test - public void testDelete() throws Exception { - final Egress acl = acl(InterfaceMode.L2); - customizer.deleteCurrentAttributes(IID, acl, writeContext); - verifyDelete(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java deleted file mode 100644 index 8a4e9213d..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizerTest.java +++ /dev/null @@ -1,205 +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.honeycomb.translate.v3po.interfaces.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManager; -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.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import java.util.Arrays; -import java.util.Collections; -import org.junit.Test; -import org.mockito.ArgumentMatcher; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.AceBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.ActionsBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.MatchesBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Deny; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.PermitBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6Builder; -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.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ietf.acl.IngressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class IetfAclCustomizerTest extends WriterCustomizerTest { - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - VppInterfaceAugmentation.class).child(IetfAcl.class).child(Ingress.class); - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = EthAcl.class; - - @Mock - private AclTableContextManager aclCtx; - - private IetfAclCustomizer customizer; - private Ingress acl; - private int DENY = 0; - private int PERMIT = -1; - - @Override - protected void setUp() { - customizer = new IetfAclCustomizer(new IngressIetfAclWriter(api, aclCtx), new NamingContext("prefix", IFC_TEST_INSTANCE)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - acl = new IngressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).build() - ).build(); - } - - @Test - public void testWrite() throws WriteFailedException { - when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); - when(api.classifyAddDelSession(any())).thenReturn(future(new ClassifyAddDelSessionReply())); - - when(writeContext.readAfter(any())).thenReturn(Optional.of( - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() - .setAccessListEntries( - new AccessListEntriesBuilder().setAce(Arrays.asList(ace(permit()), ace(permit()), ace(deny()) - )).build() - ).build() - - )); - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - - customizer.writeCurrentAttributes(IID, acl, writeContext); - - final InOrder inOrder = Mockito.inOrder(api); - inOrder.verify(api).classifyAddDelTable(argThat(actionOnMissEquals(DENY))); // default action - inOrder.verify(api).classifyAddDelTable(any()); - inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(DENY))); // last deny ACE - inOrder.verify(api).classifyAddDelTable(any()); - inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(PERMIT))); - inOrder.verify(api).classifyAddDelTable(any()); - inOrder.verify(api).classifyAddDelSession(argThat(actionOnHitEquals(PERMIT))); - inOrder.verify(api).inputAclSetInterface(inputAclSetInterfaceWriteRequest()); // assignment - } - - private ArgumentMatcher actionOnMissEquals(final int action) { - return table -> table.missNextIndex == action; - } - - - private ArgumentMatcher actionOnHitEquals(final int action) { - return session -> session.hitNextIndex == action; - } - - private Deny deny() { - return new DenyBuilder().build(); - } - - private Permit permit() { - return new PermitBuilder().build(); - } - - private static Ace ace(final PacketHandling action) { - return new AceBuilder() - .setMatches(new MatchesBuilder().setAceType( - new AceIpBuilder() - .setAceIpVersion(new AceIpv6Builder().build()) - .setProtocol((short) 1) - .build() - ).build()) - .setActions(new ActionsBuilder().setPacketHandling(action).build()) - .build(); - } - - @Test - public void testDelete() throws WriteFailedException { - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - when(api.classifyAddDelTable(any())).thenReturn(future(new ClassifyAddDelTableReply())); - when(aclCtx.getEntry(IF_INDEX, mappingContext)).thenReturn(Optional.of( - new MappingEntryBuilder() - .setIndex(IF_INDEX) - .setL2TableId(1) - .setIp4TableId(2) - .setIp6TableId(3) - .build())); - - customizer.deleteCurrentAttributes(IID, acl, writeContext); - - final ClassifyTableByInterface expectedRequest = new ClassifyTableByInterface(); - expectedRequest.swIfIndex = IF_INDEX; - verify(api).inputAclSetInterface(inputAclSetInterfaceDeleteRequest()); - verify(api).classifyAddDelTable(classifyAddDelTable(1)); - verify(api).classifyAddDelTable(classifyAddDelTable(2)); - verify(api).classifyAddDelTable(classifyAddDelTable(3)); - } - - private static InputAclSetInterface inputAclSetInterfaceDeleteRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.swIfIndex = IF_INDEX; - request.l2TableIndex = 1; - request.ip4TableIndex = 2; - request.ip6TableIndex = 3; - return request; - } - - private static ClassifyAddDelTable classifyAddDelTable(final int tableIndex) { - final ClassifyAddDelTable reply = new ClassifyAddDelTable(); - reply.tableIndex = tableIndex; - return reply; - } - - private static InputAclSetInterface inputAclSetInterfaceWriteRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.swIfIndex = IF_INDEX; - request.isAdd = 1; - request.l2TableIndex = -1; - request.ip4TableIndex = -1; - request.ip6TableIndex = 0; - return request; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java deleted file mode 100644 index d4cfd6104..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceAclCustomizerTest.java +++ /dev/null @@ -1,140 +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.honeycomb.translate.v3po.interfaces.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -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.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import org.junit.Test; -import org.mockito.Mock; -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.vpp.acl.rev161214.acl.base.attributes.Ip4Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceAclCustomizerTest extends WriterCustomizerTest { - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUBIF_NAME = "local0.0"; - private static final int SUBIF_INDEX = 11; - private static final long SUBIF_ID = 0; - private static final String TABLE_NAME = "table0"; - private static final int TABLE_INDEX = 123; - - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(Acl.class).child(Ingress.class); - - @Mock - private VppClassifierContextManager classifyTableContext; - - private SubInterfaceAclCustomizer customizer; - - @Override - protected void setUp() throws Exception { - customizer = new SubInterfaceAclCustomizer(api, new NamingContext("prefix", IFC_TEST_INSTANCE), - classifyTableContext); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); - when(classifyTableContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - } - - @Test - public void testCreate() throws WriteFailedException { - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext); - verify(api).inputAclSetInterface(expectedIp4AclRequest()); - } - - @Test(expected = WriteFailedException.class) - public void testCreateFailed() throws WriteFailedException { - when(api.inputAclSetInterface(any())).thenReturn(failedFuture()); - customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext); - } - - @Test(expected = UnsupportedOperationException.class) - public void testUpdate() throws WriteFailedException { - customizer.updateCurrentAttributes(IID, ip4Acl(), ip6Acl(), writeContext); - } - - @Test - public void testDelete() throws Exception { - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - customizer.deleteCurrentAttributes(IID, ip6Acl(), writeContext); - verify(api).inputAclSetInterface(expectedIp6AclRequest()); - } - - @Test(expected = WriteFailedException.class) - public void testDeleteFailed() throws WriteFailedException { - when(api.inputAclSetInterface(any())).thenReturn(failedFuture()); - customizer.deleteCurrentAttributes(IID, ip4Acl(), writeContext); - } - - private Ingress ip4Acl() { - final IngressBuilder builder = new IngressBuilder(); - final Ip4Acl acl = new Ip4AclBuilder().setClassifyTable(TABLE_NAME).build(); - builder.setIp4Acl(acl); - return builder.build(); - } - - private InputAclSetInterface expectedIp4AclRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = 1; - request.l2TableIndex = -1; - request.ip4TableIndex = TABLE_INDEX; - request.ip6TableIndex = -1; - request.swIfIndex = SUBIF_INDEX; - return request; - } - - private Ingress ip6Acl() { - final IngressBuilder builder = new IngressBuilder(); - final Ip6Acl acl = new Ip6AclBuilder().setClassifyTable(TABLE_NAME).build(); - builder.setIp6Acl(acl); - return builder.build(); - } - - private InputAclSetInterface expectedIp6AclRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.isAdd = 0; - request.l2TableIndex = -1; - request.ip4TableIndex = -1; - request.ip6TableIndex = TABLE_INDEX; - request.swIfIndex = SUBIF_INDEX; - return request; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java deleted file mode 100644 index 75f2b8ec8..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizerTest.java +++ /dev/null @@ -1,154 +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.honeycomb.translate.v3po.interfaces.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManager; -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.core.dto.ClassifyTableByInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; -import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; -import java.util.Collections; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.EthAcl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder; -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.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessListsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.IetfAcl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.ietf.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceIetfAclCustomizerTest extends WriterCustomizerTest { - - private static final String IFC_TEST_INSTANCE = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUBIF_NAME = "local0.123"; - private static final int SUBIF_INDEX = 2; - private static final long SUB_IF_ID = 123; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)).child(IetfAcl.class).child(Ingress.class); - private static final String ACL_NAME = "acl1"; - private static final Class ACL_TYPE = EthAcl.class; - - private SubInterfaceIetfAclCustomizer customizer; - private Ingress acl; - - @Mock - private AclTableContextManager aclCtx; - - @Override - protected void setUp() { - customizer = - new SubInterfaceIetfAclCustomizer(new IngressIetfAclWriter(api, aclCtx), new NamingContext("prefix", IFC_TEST_INSTANCE)); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - - acl = new IngressBuilder().setAccessLists( - new AccessListsBuilder().setAcl( - Collections.singletonList(new AclBuilder() - .setName(ACL_NAME) - .setType(ACL_TYPE) - .build()) - ).build() - ).build(); - } - - private static InputAclSetInterface inputAclSetInterfaceWriteRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.swIfIndex = SUBIF_INDEX; - request.isAdd = 1; - request.l2TableIndex = -1; - request.ip4TableIndex = -1; - request.ip6TableIndex = -1; - return request; - } - - @Test - public void testDelete() throws WriteFailedException { - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - when(aclCtx.getEntry(SUBIF_INDEX, mappingContext)).thenReturn(Optional.of( - new MappingEntryBuilder() - .setIndex(SUBIF_INDEX) - .setL2TableId(-1) - .setIp4TableId(-1) - .setIp6TableId(-1) - .build())); - - customizer.deleteCurrentAttributes(IID, acl, writeContext); - - final ClassifyTableByInterface expectedRequest = new ClassifyTableByInterface(); - expectedRequest.swIfIndex = SUBIF_INDEX; - verify(api).inputAclSetInterface(inputAclSetInterfaceDeleteRequest()); - } - - private static InputAclSetInterface inputAclSetInterfaceDeleteRequest() { - final InputAclSetInterface request = new InputAclSetInterface(); - request.swIfIndex = SUBIF_INDEX; - request.l2TableIndex = -1; - request.ip4TableIndex = -1; - request.ip6TableIndex = -1; - return request; - } - - @Test - public void testWrite() throws WriteFailedException { - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE); - - when(writeContext.readAfter(IID.firstIdentifierOf(SubInterface.class))).thenReturn(Optional.of( - new SubInterfaceBuilder().build() - )); - - when(writeContext.readAfter(io.fd.honeycomb.translate.v3po.interfaces.acl.IetfAclWriter.ACL_ID.child( - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl.class, - new AclKey(ACL_NAME, ACL_TYPE)))).thenReturn(Optional.of( - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder() - .setAccessListEntries( - new AccessListEntriesBuilder().setAce(Collections.emptyList()).build() - ).build() - )); - - when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply())); - - customizer.writeCurrentAttributes(IID, acl, writeContext); - - verify(api).inputAclSetInterface(inputAclSetInterfaceWriteRequest()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java deleted file mode 100644 index 00b424d9d..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java +++ /dev/null @@ -1,338 +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.honeycomb.translate.v3po.interfaces.ip; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.v3po.interfaces.ip.subnet.validation.SubnetValidationException; -import io.fd.honeycomb.translate.v3po.interfaces.ip.subnet.validation.SubnetValidator; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentMatcher; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -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.ip.rev140616.Interface1; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.NetmaskBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddress; -import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddressReply; - -public class Ipv4AddressCustomizerTest extends WriterCustomizerTest { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IFACE_NAME = "eth0"; - private static final int IFACE_ID = 123; - - @Mock - private SubnetValidator subnetValidator; - - private NamingContext interfaceContext; - private Ipv4AddressCustomizer customizer; - - @Before - public void setUp() throws Exception { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - - customizer = new Ipv4AddressCustomizer(api, interfaceContext, subnetValidator); - - doReturn(future(new IpAddressDetailsReplyDump())).when(api).ipAddressDump(any()); - when(writeContext.readAfter(Mockito.any())) - .thenReturn(Optional.of(new Ipv4Builder().setAddress(Collections.emptyList()).build())); - } - - private static InstanceIdentifier
getAddressId(final String ifaceName) { - return InstanceIdentifier.builder(Interfaces.class) - .child(Interface.class, new InterfaceKey(ifaceName)) - .augmentation(Interface1.class) - .child(Ipv4.class) - .child(Address.class) - .build(); - } - - private void whenSwInterfaceAddDelAddressThenSuccess() { - doReturn(future(new SwInterfaceAddDelAddressReply())).when(api).swInterfaceAddDelAddress(any(SwInterfaceAddDelAddress.class)); - } - - private void whenSwInterfaceAddDelAddressThenFailure() { - doReturn(failedFuture()).when(api).swInterfaceAddDelAddress(any(SwInterfaceAddDelAddress.class)); - } - - @Test - public void testAddPrefixLengthIpv4Address() throws Exception { - doNothing().when(subnetValidator).checkNotAddingToSameSubnet(Mockito.anyList()); - - final InstanceIdentifier
id = getAddressId(IFACE_NAME); - when(writeContext.readBefore(id)).thenReturn(Optional.absent()); - - Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); - Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); - - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - whenSwInterfaceAddDelAddressThenSuccess(); - - customizer.writeCurrentAttributes(id, data, writeContext); - - verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, - (byte) 1, (byte) 24)); - } - - @Test - public void testAddPrefixLengthIpv4AddressFailed() throws Exception { - final InstanceIdentifier
id = getAddressId(IFACE_NAME); - when(writeContext.readBefore(id)).thenReturn(Optional.absent()); - - Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); - Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); - - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - whenSwInterfaceAddDelAddressThenFailure(); - - try { - customizer.writeCurrentAttributes(id, data, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).swInterfaceAddDelAddress( - generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, - (byte) 1, (byte) 24)); - return; - } - fail("WriteFailedException was expected"); - } - - @Test - public void testAddPrefixLengthIpv4AddressConflicted() throws Exception { - - final InstanceIdentifier
id = getAddressId(IFACE_NAME); - when(writeContext.readBefore(id)).thenReturn(Optional.absent()); - - Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); - Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); - final List
addressList = Arrays.asList(data); - - //throws when validation invoked - doThrow(SubnetValidationException.forConflictingData((short) 24, Arrays.asList(data))).when(subnetValidator) - .checkNotAddingToSameSubnet(addressList); - - //fake data return from WriteContext - doReturn(Optional.of(new Ipv4Builder().setAddress(addressList).build())).when(writeContext) - .readAfter(argThat(matchInstanceIdentifier(Ipv4.class))); - - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - - try { - customizer.writeCurrentAttributes(id, data, writeContext); - } catch (WriteFailedException e) { - //verifies if cause of exception is correct type - assertTrue(e.getCause() instanceof SubnetValidationException); - - //verify that validation call was invoked with data from writeContext - verify(subnetValidator, times(1)).checkNotAddingToSameSubnet(addressList); - } - - } - - private static ArgumentMatcher> matchInstanceIdentifier( - Class desiredClass) { - return o -> o instanceof InstanceIdentifier && (o.getTargetType().equals(desiredClass)); - } - - @Test(expected = WriteFailedException.UpdateFailedException.class) - public void testUpdate() throws Exception { - final Address data = mock(Address.class); - customizer.updateCurrentAttributes(getAddressId(IFACE_NAME), data, data, writeContext); - } - - private SwInterfaceAddDelAddress generateSwInterfaceAddDelAddressRequest(final byte[] address, final byte isAdd, - final byte prefixLength) { - final SwInterfaceAddDelAddress request = new SwInterfaceAddDelAddress(); - request.swIfIndex = IFACE_ID; - request.isAdd = isAdd; - request.isIpv6 = 0; - request.delAll = 0; - request.addressLength = prefixLength; - request.address = address; - return request; - } - - @Test - public void testDeletePrefixLengthIpv4Address() throws Exception { - final InstanceIdentifier
id = getAddressId(IFACE_NAME); - - Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); - Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); - - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - whenSwInterfaceAddDelAddressThenSuccess(); - - customizer.deleteCurrentAttributes(id, data, writeContext); - - verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, - (byte) 0, (byte) 24)); - } - - @Test - public void testDeletePrefixLengthIpv4AddressFailed() throws Exception { - final InstanceIdentifier
id = getAddressId(IFACE_NAME); - - Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); - Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(length).build(); - - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - whenSwInterfaceAddDelAddressThenFailure(); - - try { - customizer.deleteCurrentAttributes(id, data, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).swInterfaceAddDelAddress( - generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, - (byte) 0, (byte) 24)); - return; - } - fail("WriteFailedException was expec16ted"); - } - - @Test - public void testNetmaskFailed() { - final int expectedPrefixLength = 1; - final String stringMask = "128.0.0.0"; - final InstanceIdentifier
id = getAddressId(IFACE_NAME); - when(writeContext.readBefore(id)).thenReturn(Optional.absent()); - - Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - Netmask subnet = new NetmaskBuilder().setNetmask(new DottedQuad(stringMask)).build(); - Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build(); - - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - whenSwInterfaceAddDelAddressThenFailure(); - - try { - customizer.writeCurrentAttributes(id, data, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, - (byte) 1, (byte) expectedPrefixLength)); - return; - } - fail("WriteFailedException was expec16ted"); - - } - - private void testSingleNetmask(final int expectedPrefixLength, final String stringMask) throws Exception { - final InstanceIdentifier
id = getAddressId(IFACE_NAME); - when(writeContext.readBefore(id)).thenReturn(Optional.absent()); - - Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - Netmask subnet = new NetmaskBuilder().setNetmask(new DottedQuad(stringMask)).build(); - Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build(); - - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - whenSwInterfaceAddDelAddressThenSuccess(); - - customizer.writeCurrentAttributes(id, data, writeContext); - - verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1}, - (byte) 1, (byte) expectedPrefixLength)); - } - - private void testSingleIllegalNetmask(final String stringMask) throws Exception { - try { - final InstanceIdentifier
id = getAddressId(IFACE_NAME); - when(writeContext.readBefore(id)).thenReturn(Optional.absent()); - - Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - Netmask subnet = new NetmaskBuilder().setNetmask(new DottedQuad(stringMask)).build(); - Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build(); - - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - whenSwInterfaceAddDelAddressThenSuccess(); - - customizer.writeCurrentAttributes(id, data, writeContext); - } catch (IllegalArgumentException e) { - return; - } - fail("IllegalArgumentException expected"); - - } - - /** - * Test contiguous netmask length from QuadDotted notation - */ - @Test - public void testNetmaskLength() throws Exception { - testSingleNetmask(1, "128.0.0.0"); - testSingleNetmask(2, "192.0.0.0"); - testSingleNetmask(8, "255.0.0.0"); - testSingleNetmask(9, "255.128.0.0"); - testSingleNetmask(16, "255.255.0.0"); - testSingleNetmask(24, "255.255.255.0"); - } - - @Test - public void testNetmaskIllegal() throws Exception { - testSingleIllegalNetmask(""); - testSingleIllegalNetmask("."); - testSingleIllegalNetmask(".255"); - testSingleIllegalNetmask("255"); - testSingleIllegalNetmask("255."); - testSingleIllegalNetmask("255.255"); - testSingleIllegalNetmask("255.255.0"); - testSingleIllegalNetmask("255.255.255."); - testSingleIllegalNetmask("255.255.255.256"); - testSingleIllegalNetmask("0.0.0.0"); - testSingleIllegalNetmask("10.10.10.10"); - testSingleIllegalNetmask("255.1.255.0"); - testSingleIllegalNetmask("255.255.255.255"); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java deleted file mode 100644 index c856d9b8c..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java +++ /dev/null @@ -1,120 +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.honeycomb.translate.v3po.interfaces.ip; - -import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import io.fd.honeycomb.translate.vpp.util.Ipv4Translator; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -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.ip.rev140616.Interface1; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.IpNeighborAddDel; -import io.fd.vpp.jvpp.core.dto.IpNeighborAddDelReply; - -public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest implements Ipv4Translator { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IFACE_NAME = "parent"; - private static final int IFACE_ID = 5; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) - .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class); - - private Ipv4NeighbourCustomizer customizer; - - @Override - public void setUp() { - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - customizer = new Ipv4NeighbourCustomizer(api, new NamingContext("prefix", IFC_CTX_NAME)); - } - - @Test - public void testWriteCurrentAttributes() throws WriteFailedException { - when(api.ipNeighborAddDel(any())).thenReturn(future(new IpNeighborAddDelReply())); - customizer.writeCurrentAttributes(IID, getData(), writeContext); - verify(api).ipNeighborAddDel(getExpectedRequest(true)); - } - - @Test - public void testWriteCurrentAttributesFailed() { - when(api.ipNeighborAddDel(any())).thenReturn(failedFuture()); - try { - customizer.writeCurrentAttributes(IID, getData(), writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).ipNeighborAddDel(getExpectedRequest(true)); - return; - } - fail("WriteFailedException expected"); - } - @Test(expected = UnsupportedOperationException.class) - public void testUpdateCurrentAttributes() throws WriteFailedException { - customizer.updateCurrentAttributes(IID, getData(), getData(), writeContext); - } - - @Test - public void testDeleteCurrentAttributes() throws WriteFailedException { - when(api.ipNeighborAddDel(any())).thenReturn(future(new IpNeighborAddDelReply())); - customizer.deleteCurrentAttributes(IID, getData(), writeContext); - verify(api).ipNeighborAddDel(getExpectedRequest(false)); - } - - @Test - public void testDeleteCurrentAttributesFailed() { - when(api.ipNeighborAddDel(any())).thenReturn(failedFuture()); - try { - customizer.deleteCurrentAttributes(IID, getData(), writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).ipNeighborAddDel(getExpectedRequest(false)); - return; - } - fail("WriteFailedException expected"); - } - - private Neighbor getData() { - final Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - final PhysAddress mac = new PhysAddress("aa:bb:cc:ee:11:22"); - return new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build(); - } - private IpNeighborAddDel getExpectedRequest(final boolean isAdd) { - final IpNeighborAddDel request = new IpNeighborAddDel(); - request.isIpv6 = 0; - request.isAdd = booleanToByte(isAdd); - request.isStatic = 1; - request.dstAddress = new byte[] {(byte) 192, (byte) 168, 2, 1}; - request.macAddress = new byte[] {(byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xee, 0x11, 0x22}; - request.swIfIndex = IFACE_ID; - return request; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java deleted file mode 100644 index 269fc5212..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java +++ /dev/null @@ -1,144 +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.honeycomb.translate.v3po.interfaces.ip; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -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.DottedQuad; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.Subnet; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.Netmask; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.NetmaskBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddress; -import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddressReply; - -public class SubInterfaceIpv4AddressCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IFACE_NAME = "eth0"; - private static final int IFACE_INDEX = 0; - private static final String SUBIF_NAME = "eth0.1"; - private static final long SUBIF_ID = 1; - private static final int SUBIF_INDEX = 123; - private static final InstanceIdentifier
IID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) - .augmentation(SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(Ipv4.class).child(Address.class); - - private SubInterfaceIpv4AddressCustomizer customizer; - - @Override - protected void setUp() { - customizer = new SubInterfaceIpv4AddressCustomizer(api, new NamingContext("prefix", IFC_CTX_NAME)); - defineMapping(mappingContext, IFACE_NAME, IFACE_INDEX, IFC_CTX_NAME); - defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_CTX_NAME); - } - - @Test - public void testWrite() throws WriteFailedException { - when(api.swInterfaceAddDelAddress(any())).thenReturn(future(new SwInterfaceAddDelAddressReply())); - customizer.writeCurrentAttributes(IID, address(prefixLength()), writeContext); - verify(api).swInterfaceAddDelAddress(expectedRequest(true)); - } - - @Test - public void testWriteFailed() { - when(api.swInterfaceAddDelAddress(any())).thenReturn(failedFuture()); - try { - customizer.writeCurrentAttributes(IID, address(prefixLength()), writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).swInterfaceAddDelAddress(expectedRequest(true)); - return; - } - fail("WriteFailedException expected"); - } - - @Test - public void testDelete() throws WriteFailedException { - when(api.swInterfaceAddDelAddress(any())).thenReturn(future(new SwInterfaceAddDelAddressReply())); - customizer.deleteCurrentAttributes(IID, address(netmask()), writeContext); - verify(api).swInterfaceAddDelAddress(expectedRequest(false)); - } - - @Test - public void testDeleteFailed() { - when(api.swInterfaceAddDelAddress(any())).thenReturn(failedFuture()); - try { - customizer.deleteCurrentAttributes(IID, address(netmask()), writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).swInterfaceAddDelAddress(expectedRequest(false)); - return; - } - fail("WriteFailedException expected"); - } - - private SwInterfaceAddDelAddress expectedRequest(boolean isAdd) { - final SwInterfaceAddDelAddress request = new SwInterfaceAddDelAddress(); - request.isAdd = booleanToByte(isAdd); - request.swIfIndex = SUBIF_INDEX; - request.isIpv6 = 0; - request.delAll = 0; - request.addressLength = 24; - request.address = new byte[] {(byte) 192, (byte) 168, 2, 1}; - return request; - } - - @Test(expected = WriteFailedException.UpdateFailedException.class) - public void testUpdate() throws Exception { - final Address address = address(prefixLength()); - customizer.updateCurrentAttributes(IID, address, address, writeContext); - } - - private Address address(final Subnet subnet) { - final Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); - return new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build(); - } - - private PrefixLength prefixLength() { - return new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build(); - } - - private Netmask netmask() { - return new NetmaskBuilder().setNetmask(new DottedQuad("255.255.255.0")).build(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidatorTest.java deleted file mode 100644 index 7c3088f99..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/subnet/validation/SubnetValidatorTest.java +++ /dev/null @@ -1,88 +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.honeycomb.translate.v3po.interfaces.ip.subnet.validation; - - -import com.google.common.collect.Lists; -import java.util.List; -import org.junit.Before; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.NetmaskBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; - -public class SubnetValidatorTest { - - private SubnetValidator subnetValidator; - - @Before - public void init() { - subnetValidator = new SubnetValidator(); - } - - @Test(expected = SubnetValidationException.class) - public void testValidateNegativeSameTypes() throws SubnetValidationException { - List
addresses = Lists.newArrayList(); - - addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) - .build()); - addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) - .build()); - - subnetValidator.checkNotAddingToSameSubnet(addresses); - } - - @Test(expected = SubnetValidationException.class) - public void testValidateNegativeMixedTypes() throws SubnetValidationException { - List
addresses = Lists.newArrayList(); - - addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) - .build()); - addresses.add(new AddressBuilder() - .setSubnet(new NetmaskBuilder().setNetmask(new DottedQuad("255.255.255.0")).build()) - .build()); - - subnetValidator.checkNotAddingToSameSubnet(addresses); - } - - @Test - public void testValidatePositiveSameTypes() throws SubnetValidationException { - List
addresses = Lists.newArrayList(); - - addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) - .build()); - addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 25).build()) - .build()); - - subnetValidator.checkNotAddingToSameSubnet(addresses); - } - - @Test - public void testValidatePositiveMixedTypes() throws SubnetValidationException { - List
addresses = Lists.newArrayList(); - - addresses.add(new AddressBuilder().setSubnet(new PrefixLengthBuilder().setPrefixLength((short) 24).build()) - .build()); - addresses.add(new AddressBuilder() - .setSubnet(new NetmaskBuilder().setNetmask(new DottedQuad("255.255.0.0")).build()) - .build()); - - subnetValidator.checkNotAddingToSameSubnet(addresses); - } -} 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 deleted file mode 100644 index e1a791845..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java +++ /dev/null @@ -1,312 +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.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.rev161214.Operation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces._interface.PbbRewrite; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.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/EthernetCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/EthernetCustomizerTest.java deleted file mode 100644 index a04b022ea..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/EthernetCustomizerTest.java +++ /dev/null @@ -1,90 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import io.fd.honeycomb.vpp.test.util.InterfaceDumpHelper; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.EthernetStateAttributes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Ethernet; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.EthernetBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; - -public class EthernetCustomizerTest extends ReaderCustomizerTest implements - InterfaceDumpHelper { - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(VppInterfaceStateAugmentation.class).child(Ethernet.class); - private NamingContext interfaceContext; - - public EthernetCustomizerTest() { - super(Ethernet.class, VppInterfaceStateAugmentationBuilder.class); - } - - @Override - protected void setUp() throws Exception { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new EthernetCustomizer(api, interfaceContext); - } - - private void testRead(final int linkDuplex, final EthernetStateAttributes.Duplex duplex) throws ReadFailedException { - final EthernetBuilder builder = mock(EthernetBuilder.class); - final short mtu = 123; - whenSwInterfaceDumpThenReturn(api, ifaceDetails(mtu, linkDuplex)); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - verify(builder).setMtu((int)mtu); - verify(builder).setDuplex(duplex); - } - - private SwInterfaceDetails ifaceDetails(final short mtu, final int duplex) { - final SwInterfaceDetails details = new SwInterfaceDetails(); - details.swIfIndex = IF_INDEX; - details.linkMtu = mtu; - details.linkDuplex = (byte)duplex; - return details; - } - - @Test - public void testReadHalfDuplex() throws ReadFailedException { - testRead(1, EthernetStateAttributes.Duplex.Half); - } - - @Test - public void testReadFullDuplex() throws ReadFailedException { - testRead(2, EthernetStateAttributes.Duplex.Full); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/GreCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/GreCustomizerTest.java deleted file mode 100644 index fa5368629..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/GreCustomizerTest.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.honeycomb.translate.v3po.interfacesstate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -import com.google.common.collect.Lists; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Gre; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.GreBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.GreTunnelDetails; -import io.fd.vpp.jvpp.core.dto.GreTunnelDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.GreTunnelDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; - -public class GreCustomizerTest extends ReaderCustomizerTest { - - private static final String IFACE_NAME = "ifc1"; - private static final int IFACE_ID = 0; - private static final String IFC_CTX_NAME = "ifc-test-instance"; - - private NamingContext interfacesContext; - static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) - .augmentation(VppInterfaceStateAugmentation.class).child(Gre.class); - - public GreCustomizerTest() { - super(Gre.class, VppInterfaceStateAugmentationBuilder.class); - } - - @Override - public void setUp() throws UnknownHostException, VppInvocationException { - interfacesContext = new NamingContext("gre-tunnel", IFC_CTX_NAME); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - - final SwInterfaceDetails v = new SwInterfaceDetails(); - v.interfaceName = "gre-tunnel4".getBytes(); - final Map map = new HashMap<>(); - map.put(0, v); - cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, map); - - final GreTunnelDetailsReplyDump value = new GreTunnelDetailsReplyDump(); - final GreTunnelDetails greTunnelDetails = new GreTunnelDetails(); - greTunnelDetails.isIpv6 = 0; - greTunnelDetails.dstAddress = InetAddress.getByName("1.2.3.4").getAddress(); - greTunnelDetails.srcAddress = InetAddress.getByName("1.2.3.5").getAddress(); - greTunnelDetails.outerFibId = 55; - greTunnelDetails.swIfIndex = 0; - value.greTunnelDetails = Lists.newArrayList(greTunnelDetails); - - doReturn(future(value)).when(api).greTunnelDump(any(GreTunnelDump.class)); - } - - @Test - public void testReadCurrentAttributes() throws Exception { - final GreBuilder builder = getCustomizer().getBuilder(IID); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - - assertEquals(55, builder.getOuterFibId().intValue()); - - assertNull(builder.getSrc().getIpv6Address()); - assertNotNull(builder.getSrc().getIpv4Address()); - assertEquals("1.2.3.5", builder.getSrc().getIpv4Address().getValue()); - - assertNull(builder.getDst().getIpv6Address()); - assertNotNull(builder.getDst().getIpv4Address()); - assertEquals("1.2.3.4", builder.getDst().getIpv4Address().getValue()); - - verify(api).greTunnelDump(any(GreTunnelDump.class)); - } - - @Test(expected = NullPointerException.class) - public void testReadCurrentAttributesVppNameNotCached() throws Exception { - InterfaceCustomizer.getCachedInterfaceDump(cache).remove(0); - - final GreBuilder builder = getCustomizer().getBuilder(IID); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - } - - @Test - public void testReadCurrentAttributesWrongType() throws Exception { - final SwInterfaceDetails v = new SwInterfaceDetails(); - v.interfaceName = "tap-2".getBytes(); - InterfaceCustomizer.getCachedInterfaceDump(cache).put(0, v); - - final GreBuilder builder = getCustomizer().getBuilder(IID); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - - // Should be ignored - verifyZeroInteractions(api); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new GreCustomizer(api, interfacesContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceCustomizerTest.java deleted file mode 100644 index 581da29d7..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceCustomizerTest.java +++ /dev/null @@ -1,201 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.v3po.DisabledInterfacesManager; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; -import io.fd.honeycomb.vpp.test.util.InterfaceDumpHelper; -import java.util.Arrays; -import java.util.List; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; - -public class InterfaceCustomizerTest extends ListReaderCustomizerTest - implements InterfaceDataTranslator, InterfaceDumpHelper { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IFACE0_NAME = "eth0"; - private static final String IFACE1_NAME = "eth1"; - private static final String SUB_IFACE_NAME = "eth1.1"; - private static final int IFACE0_ID = 0; - private static final int IFACE1_ID = 1; - private static final int SUB_IFACE_ID = 2; - - private NamingContext interfacesContext; - @Mock - private DisabledInterfacesManager interfaceDisableContext; - - public InterfaceCustomizerTest() { - super(Interface.class, InterfacesStateBuilder.class); - } - - @Override - public void setUp() { - interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, IFACE0_NAME, IFACE0_ID, IFC_CTX_NAME); - defineMapping(mappingContext, IFACE1_NAME, IFACE1_ID, IFC_CTX_NAME); - defineMapping(mappingContext, SUB_IFACE_NAME, SUB_IFACE_ID, IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new InterfaceCustomizer(api, interfacesContext, interfaceDisableContext); - } - - private void verifySwInterfaceDumpWasInvoked(final int nameFilterValid, final String ifaceName, - final int dumpIfcsInvocationCount) - throws VppInvocationException { - final SwInterfaceDump expected = new SwInterfaceDump(); - expected.nameFilterValid = (byte) nameFilterValid; - expected.nameFilter = ifaceName.getBytes(); - verify(api, times(dumpIfcsInvocationCount)).swInterfaceDump(expected); - } - - private void assertIfacesAreEqual(final Interface iface, final SwInterfaceDetails details) { - assertEquals(iface.getName(), new String(details.interfaceName)); - Assert.assertEquals(yangIfIndexToVpp(iface.getIfIndex().intValue()), details.swIfIndex); - assertEquals(iface.getPhysAddress().getValue(), vppPhysAddrToYang(details.l2Address)); - } - - @Test - public void testReadCurrentAttributes() throws Exception { - final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(IFACE0_NAME)); - final InterfaceBuilder builder = getCustomizer().getBuilder(id); - - final SwInterfaceDetails iface = new SwInterfaceDetails(); - iface.interfaceName = IFACE0_NAME.getBytes(); - iface.swIfIndex = 0; - iface.linkSpeed = 1; - iface.l2AddressLength = 6; - iface.l2Address = new byte[iface.l2AddressLength]; - whenSwInterfaceDumpThenReturn(api, iface); - - getCustomizer().readCurrentAttributes(id, builder, ctx); - - verifySwInterfaceDumpWasInvoked(1, IFACE0_NAME, 1); - assertIfacesAreEqual(builder.build(), iface); - } - - @Test - public void testReadCurrentAttributesFailed() throws Exception { - final String ifaceName = IFACE0_NAME; - final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(ifaceName)); - final InterfaceBuilder builder = getCustomizer().getBuilder(id); - - whenSwInterfaceDumpThenReturn(api); - - try { - getCustomizer().readCurrentAttributes(id, builder, ctx); - } catch (IllegalArgumentException e) { - verifySwInterfaceDumpWasInvoked(0, ifaceName, 2); - return; - } - - fail("ReadFailedException was expected"); - } - - @Test - public void testReadSubInterface() throws Exception { - final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(SUB_IFACE_NAME)); - final InterfaceBuilder builder = mock(InterfaceBuilder.class); - - final SwInterfaceDetails iface = new SwInterfaceDetails(); - iface.interfaceName = SUB_IFACE_NAME.getBytes(); - iface.swIfIndex = 2; - iface.supSwIfIndex = 1; - iface.subId = 1; - whenSwInterfaceDumpThenReturn(api, iface); - - getCustomizer().readCurrentAttributes(id, builder, ctx); - - verifySwInterfaceDumpWasInvoked(1, SUB_IFACE_NAME, 1); - verifyZeroInteractions(builder); - } - - @Test - public void testGetAllIds() throws Exception { - final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class); - - final SwInterfaceDetails swIf0 = new SwInterfaceDetails(); - swIf0.swIfIndex = 0; - swIf0.interfaceName = IFACE0_NAME.getBytes(); - final SwInterfaceDetails swIf1 = new SwInterfaceDetails(); - swIf1.swIfIndex = 1; - swIf1.interfaceName = IFACE1_NAME.getBytes(); - final SwInterfaceDetails swSubIf1 = new SwInterfaceDetails(); - swSubIf1.swIfIndex = 2; - swSubIf1.subId = 1; - swSubIf1.supSwIfIndex = 1; - swSubIf1.interfaceName = SUB_IFACE_NAME.getBytes(); - whenSwInterfaceDumpThenReturn(api, swIf0, swIf1, swSubIf1); - - final List expectedIds = Arrays.asList(new InterfaceKey(IFACE0_NAME), new InterfaceKey( - IFACE1_NAME)); - final List actualIds = getCustomizer().getAllIds(id, ctx); - - verifySwInterfaceDumpWasInvoked(0, "", 1); - - // sub-interface should not be on the list - assertEquals(expectedIds, actualIds); - } - - @Test - public void testGetAllIdsWithDisabled() throws Exception { - final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class); - - doReturn(true).when(interfaceDisableContext).isInterfaceDisabled(1, mappingContext); - - final SwInterfaceDetails swIf0 = new SwInterfaceDetails(); - swIf0.swIfIndex = 0; - swIf0.interfaceName = IFACE0_NAME.getBytes(); - final SwInterfaceDetails swIf1 = new SwInterfaceDetails(); - swIf1.swIfIndex = 1; - swIf1.interfaceName = IFACE1_NAME.getBytes(); - whenSwInterfaceDumpThenReturn(api, swIf0, swIf1); - - final List expectedIds = Arrays.asList(new InterfaceKey(IFACE0_NAME)); - final List actualIds = getCustomizer().getAllIds(id, ctx); - - // disabled interface should not be on the list - assertEquals(expectedIds, actualIds); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslatorTest.java deleted file mode 100644 index 56e40826a..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslatorTest.java +++ /dev/null @@ -1,55 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel; - -public class InterfaceDataTranslatorTest implements InterfaceDataTranslator { - - @Test - public void testVppPhysAddrToYang() throws Exception { - assertEquals("01:02:03:04:05:06", vppPhysAddrToYang(new byte[]{1, 2, 3, 4, 5, 6})); - assertEquals("0a:0b:0c:0d:0e:0f", vppPhysAddrToYang(new byte[]{0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0})); - } - - @Test(expected = NullPointerException.class) - public void testVppPhysAddrToYangFailNullArgument() throws Exception { - vppPhysAddrToYang(null); - } - - @Test(expected = IllegalArgumentException.class) - public void testVppPhysAddrToYangInvalidByteArrayLength() throws Exception { - vppPhysAddrToYang(new byte[]{1, 2, 3, 4, 5}); - } - - @Test - public void testGetInterfaceType() { - assertEquals(Tap.class, getInterfaceType("tap0")); - assertEquals(VxlanTunnel.class, getInterfaceType("vxlan0")); - assertEquals(VxlanGpeTunnel.class, getInterfaceType("vxlan_gpe0")); - assertEquals(VhostUser.class, getInterfaceType("VirtualEthernet0/0/0")); - assertEquals(EthernetCsmacd.class, getInterfaceType("eth0.0")); - assertEquals(EthernetCsmacd.class, getInterfaceType("local0")); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/L2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/L2CustomizerTest.java deleted file mode 100644 index 6bc839a37..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/L2CustomizerTest.java +++ /dev/null @@ -1,145 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; -import io.fd.vpp.jvpp.core.dto.BridgeDomainSwIfDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; - -public class L2CustomizerTest extends ReaderCustomizerTest { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String BD_CTX_NAME = "bd-test-instance"; - private NamingContext interfaceContext; - private NamingContext bridgeDomainContext; - - public L2CustomizerTest() { - super(L2.class, VppInterfaceStateAugmentationBuilder.class); - } - - @Override - public void setUp() { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - bridgeDomainContext = new NamingContext("generatedBDName", BD_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new L2Customizer(api, interfaceContext, bridgeDomainContext); - } - - private InstanceIdentifier getL2Id(final String name) { - return InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(name)) - .augmentation( - VppInterfaceStateAugmentation.class).child(L2.class); - } - - private void whenBridgeDomainSwIfDumpThenReturn(final List bdSwIfList, - final List bridgeDomainDetailses) { - final BridgeDomainDetailsReplyDump reply = new BridgeDomainDetailsReplyDump(); - reply.bridgeDomainSwIfDetails = bdSwIfList; - reply.bridgeDomainDetails = bridgeDomainDetailses; - when(api.bridgeDomainSwIfDump(any(BridgeDomainDump.class))).thenReturn(future(reply)); - } - - - private BridgeDomainSwIfDetails generateBdSwIfDetails(final int ifId, final int bdId) { - final BridgeDomainSwIfDetails bdSwIfDetails = new BridgeDomainSwIfDetails(); - bdSwIfDetails.swIfIndex = ifId; - bdSwIfDetails.shg = 1; - bdSwIfDetails.bdId = bdId; - return bdSwIfDetails; - } - - private Interconnection generateInterconnection(final int ifId, final String bdName, final Boolean bvi) { - final BridgeBasedBuilder bbBuilder = new BridgeBasedBuilder(); - bbBuilder.setBridgeDomain(bdName); - bbBuilder.setSplitHorizonGroup((short) 1); - if (bvi != null) { - bbBuilder.setBridgedVirtualInterface(bvi); - } else { - bbBuilder.setBridgedVirtualInterface(false); // false is default - } - return bbBuilder.build(); - } - - @Test - public void testRead() throws Exception { - final Map cachedInterfaceDump = new HashMap<>(); - final int ifId = 1; - final int bdId = 1; - final String bdName = "bd001"; - final String ifName = "eth0.sub0"; - defineMapping(mappingContext, ifName, ifId, IFC_CTX_NAME); - defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); - - final SwInterfaceDetails ifaceDetails = new SwInterfaceDetails(); - ifaceDetails.subId = ifId; - cachedInterfaceDump.put(ifId, ifaceDetails); - cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump); - - // BVIinterfaceContext - whenBridgeDomainSwIfDumpThenReturn(Collections.singletonList(generateBdSwIfDetails(ifId, bdId)), - Collections.singletonList(generateBdDetails(ifId, bdId))); - - L2Builder builder = mock(L2Builder.class); - getCustomizer().readCurrentAttributes(getL2Id(ifName), builder, ctx); - - verify(builder).setInterconnection(generateInterconnection(ifId, bdName, true)); - - // Not BVI - whenBridgeDomainSwIfDumpThenReturn(Collections.singletonList(generateBdSwIfDetails(ifId, bdId)), - Collections.singletonList(generateBdDetails(99 /* Different ifc is marked as BVI in bd details */, bdId))); - - builder = mock(L2Builder.class); - getCustomizer().readCurrentAttributes(getL2Id(ifName), builder, ctx); - - verify(builder).setInterconnection(generateInterconnection(ifId, bdName, null)); - } - - private BridgeDomainDetails generateBdDetails(final int ifId, final int bdId) { - final BridgeDomainDetails bridgeDomainDetails = new BridgeDomainDetails(); - bridgeDomainDetails.bviSwIfIndex = ifId; - bridgeDomainDetails.bdId = bdId; - return bridgeDomainDetails; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/RewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/RewriteCustomizerTest.java deleted file mode 100644 index 7ca1bd607..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/RewriteCustomizerTest.java +++ /dev/null @@ -1,114 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.translate.vpp.util.TagRewriteOperation; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -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.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1q; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.RewriteBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; - -public class RewriteCustomizerTest extends ReaderCustomizerTest { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final String VLAN_IF_NAME = "local0.1"; - private static final int VLAN_IF_INDEX = 11; - private static final int VLAN_ID = 1; - - private NamingContext interfacesContext; - - @Captor - private ArgumentCaptor> captor; - - public RewriteCustomizerTest() { - super(Rewrite.class, L2Builder.class); - } - - @Override - public void setUp() { - interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, VLAN_IF_NAME, VLAN_IF_INDEX, IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new RewriteCustomizer(api, interfacesContext); - } - - private InstanceIdentifier getVlanTagRewriteId(final String name, final long index) { - final Class> child = (Class)Rewrite.class; - final InstanceIdentifier id = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(name)).augmentation( - SubinterfaceStateAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(index)) - .child(child); - return id; - } - - @Test - public void testRead() throws ReadFailedException { - final Map cachedInterfaceDump = new HashMap<>(); - - final SwInterfaceDetails ifaceDetails = new SwInterfaceDetails(); - ifaceDetails.subId = VLAN_ID; - ifaceDetails.interfaceName = VLAN_IF_NAME.getBytes(); - ifaceDetails.vtrOp = TagRewriteOperation.translate_2_to_2.ordinal(); - ifaceDetails.subNumberOfTags = 2; - ifaceDetails.vtrTag1 = 123; - ifaceDetails.vtrTag2 = 321; - ifaceDetails.vtrPushDot1Q = 1; - cachedInterfaceDump.put(VLAN_IF_INDEX, ifaceDetails); - cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump); - - final RewriteBuilder builder = mock(RewriteBuilder.class); - - getCustomizer().readCurrentAttributes(getVlanTagRewriteId(IF_NAME, VLAN_ID), builder, ctx); - - verify(builder).setVlanType(_802dot1q.class); - verify(builder).setPopTags((short) 2); - - verify(builder).setPushTags(captor.capture()); - final List tags = captor.getValue(); - assertEquals(ifaceDetails.subNumberOfTags, tags.size()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java deleted file mode 100644 index 30c551c89..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java +++ /dev/null @@ -1,129 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; -import io.fd.honeycomb.vpp.test.util.InterfaceDumpHelper; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfacesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.VlanTagged; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; - -public class SubInterfaceCustomizerTest extends ListReaderCustomizerTest implements - InterfaceDumpHelper { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String SUPER_IF_NAME = "local0"; - private static final int SUPER_IF_INDEX = 1; - private static final String VLAN_IF_NAME = "local0.1"; - private static final int VLAN_IF_ID = 1; - private static final int VLAN_IF_INDEX = 11; - - private NamingContext interfacesContext; - - public SubInterfaceCustomizerTest() { - super(SubInterface.class, SubInterfacesBuilder.class); - } - - @Override - public void setUp() { - interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, SUPER_IF_NAME, SUPER_IF_INDEX, IFC_CTX_NAME); - defineMapping(mappingContext, VLAN_IF_NAME, VLAN_IF_INDEX, IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new SubInterfaceCustomizer(api, interfacesContext); - } - - private InstanceIdentifier getSubInterfaceId(final String name, final long id) { - return InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(name)).augmentation( - SubinterfaceStateAugmentation.class).child( - SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(id)); - } - - @Test - public void testRead() throws ReadFailedException { - final Map cachedInterfaceDump = new HashMap<>(); - - final SwInterfaceDetails ifaceDetails = new SwInterfaceDetails(); - ifaceDetails.subId = VLAN_IF_ID; - ifaceDetails.interfaceName = VLAN_IF_NAME.getBytes(); - ifaceDetails.subDot1Ad = 1; - defineMapping(mappingContext, SUPER_IF_NAME, SUPER_IF_INDEX, IFC_CTX_NAME); - defineMapping(mappingContext, VLAN_IF_NAME, VLAN_IF_INDEX, IFC_CTX_NAME); - ifaceDetails.subNumberOfTags = 2; - ifaceDetails.subOuterVlanIdAny = 1; - ifaceDetails.subInnerVlanIdAny = 1; - ifaceDetails.subExactMatch = 1; - cachedInterfaceDump.put(VLAN_IF_INDEX, ifaceDetails); - cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump); - - final SubInterfaceBuilder builder = mock(SubInterfaceBuilder.class); - getCustomizer().readCurrentAttributes(getSubInterfaceId(SUPER_IF_NAME, VLAN_IF_ID), builder, ctx); - - verify(builder).setIdentifier((long) VLAN_IF_ID); - - ArgumentCaptor tagCaptor = ArgumentCaptor.forClass(Tags.class); - verify(builder).setTags(tagCaptor.capture()); - assertEquals(ifaceDetails.subNumberOfTags, tagCaptor.getValue().getTag().size()); - - ArgumentCaptor matchCaptor = ArgumentCaptor.forClass(Match.class); - verify(builder).setMatch(matchCaptor.capture()); - final VlanTagged matchType = (VlanTagged)matchCaptor.getValue().getMatchType(); - assertTrue(matchType.getVlanTagged().isMatchExactTags()); - } - - @Test - public void testGetAllIds() throws Exception { - final SwInterfaceDetails iface = new SwInterfaceDetails(); - iface.interfaceName = VLAN_IF_NAME.getBytes(); - iface.swIfIndex = VLAN_IF_INDEX; - iface.subId = VLAN_IF_ID; - iface.supSwIfIndex = SUPER_IF_INDEX; - whenSwInterfaceDumpThenReturn(api, iface); - - final List allIds = - getCustomizer().getAllIds(getSubInterfaceId(SUPER_IF_NAME, VLAN_IF_ID), ctx); - - assertEquals(1, allIds.size()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceL2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceL2CustomizerTest.java deleted file mode 100644 index 83e84102b..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceL2CustomizerTest.java +++ /dev/null @@ -1,80 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceL2CustomizerTest extends ReaderCustomizerTest { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String BD_CTX_NAME = "bd-test-instance"; - private NamingContext interfaceContext; - private NamingContext bridgeDomainContext; - - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUB_IF_NAME = "local0.1"; - private static final long SUB_IF_ID = 1; - private static final int SUB_IF_INDEX = 11; - private InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(SubinterfaceStateAugmentation.class) - .child(SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)).child(L2.class); - - public SubInterfaceL2CustomizerTest() { - super(L2.class, SubInterfaceBuilder.class); - } - - @Override - protected void setUp() { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - bridgeDomainContext = new NamingContext("generatedBDName", BD_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - defineMapping(mappingContext, SUB_IF_NAME, SUB_IF_INDEX, IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new SubInterfaceL2Customizer(api, interfaceContext, bridgeDomainContext); - } - - @Test(expected = ReadFailedException.class) - public void testReadFailed() throws ReadFailedException { - final L2Builder builder = mock(L2Builder.class); - when(api.swInterfaceDump(any())).thenReturn(failedFuture()); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/TapCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/TapCustomizerTest.java deleted file mode 100644 index 3535085f8..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/TapCustomizerTest.java +++ /dev/null @@ -1,98 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import io.fd.honeycomb.vpp.test.util.InterfaceDumpHelper; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.TapBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetailsReplyDump; - -public class TapCustomizerTest extends ReaderCustomizerTest implements InterfaceDumpHelper { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IF_NAME = "tap1"; - private static final String TAP_NAME = "testTapName"; - private static final int IF_INDEX = 1; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(VppInterfaceStateAugmentation.class).child(Tap.class); - private NamingContext interfaceContext; - - public TapCustomizerTest() { - super(Tap.class, VppInterfaceStateAugmentationBuilder.class); - } - - @Override - protected void setUp() throws Exception { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - whenSwInterfaceDumpThenReturn(api, ifaceDetails()); - } - - private SwInterfaceDetails ifaceDetails() { - final SwInterfaceDetails details = new SwInterfaceDetails(); - details.swIfIndex = IF_INDEX; - details.interfaceName = IF_NAME.getBytes(); - return details; - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new TapCustomizer(api, interfaceContext); - } - - @Test - public void testRead() throws ReadFailedException { - final TapBuilder builder = mock(TapBuilder.class); - when(api.swInterfaceTapDump(any())).thenReturn(future(tapDump())); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - verify(builder).setTapName(TAP_NAME); - } - - @Test(expected = ReadFailedException.class) - public void testReadFailed() throws ReadFailedException { - when(api.swInterfaceTapDump(any())).thenReturn(failedFuture()); - getCustomizer().readCurrentAttributes(IID, mock(TapBuilder.class), ctx); - } - - private SwInterfaceTapDetailsReplyDump tapDump() { - final SwInterfaceTapDetailsReplyDump reply = new SwInterfaceTapDetailsReplyDump(); - final SwInterfaceTapDetails details = new SwInterfaceTapDetails(); - details.devName = TAP_NAME.getBytes(); - details.swIfIndex = IF_INDEX; - reply.swInterfaceTapDetails.add(details); - return reply; - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VhostUserCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VhostUserCustomizerTest.java deleted file mode 100644 index 90e3ed02c..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VhostUserCustomizerTest.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.honeycomb.translate.v3po.interfacesstate; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import io.fd.honeycomb.vpp.test.util.InterfaceDumpHelper; -import java.math.BigInteger; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUserRole; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUserBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetailsReplyDump; - -public class VhostUserCustomizerTest extends ReaderCustomizerTest implements - InterfaceDumpHelper { - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IF_NAME = "VirtualEthernet1"; - private static final int IF_INDEX = 1; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(VppInterfaceStateAugmentation.class).child(VhostUser.class); - - private NamingContext interfaceContext; - - public VhostUserCustomizerTest() { - super(VhostUser.class, VppInterfaceStateAugmentationBuilder.class); - } - - @Override - protected void setUp() throws Exception { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - whenSwInterfaceDumpThenReturn(api, ifaceDetails()); - } - - private SwInterfaceDetails ifaceDetails() { - final SwInterfaceDetails details = new SwInterfaceDetails(); - details.swIfIndex = IF_INDEX; - details.interfaceName = IF_NAME.getBytes(); - return details; - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new VhostUserCustomizer(api, interfaceContext); - } - - @Test - public void testRead() throws ReadFailedException { - final VhostUserBuilder builder = mock(VhostUserBuilder.class); - when(api.swInterfaceVhostUserDump(any())).thenReturn(future(vhostDump())); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - verifyVhostBuilder(builder); - } - - @Test(expected = ReadFailedException.class) - public void testReadFailed() throws ReadFailedException { - when(api.swInterfaceVhostUserDump(any())).thenReturn(failedFuture()); - getCustomizer().readCurrentAttributes(IID, mock(VhostUserBuilder.class), ctx); - } - - private SwInterfaceVhostUserDetailsReplyDump vhostDump() { - final SwInterfaceVhostUserDetailsReplyDump reply = new SwInterfaceVhostUserDetailsReplyDump(); - final SwInterfaceVhostUserDetails details = new SwInterfaceVhostUserDetails(); - details.swIfIndex = IF_INDEX; - details.interfaceName = IF_NAME.getBytes(); - details.isServer = 1; - details.features = 2; - details.numRegions = 3; - details.sockFilename = "socketName".getBytes(); - details.virtioNetHdrSz = 4; - details.sockErrno = 5; - reply.swInterfaceVhostUserDetails.add(details); - return reply; - } - - private void verifyVhostBuilder(final VhostUserBuilder builder) { - verify(builder).setRole(VhostUserRole.Server); - verify(builder).setFeatures(BigInteger.valueOf(2)); - verify(builder).setNumMemoryRegions(3L); - verify(builder).setSocket("socketName"); - verify(builder).setVirtioNetHdrSize(4L); - verify(builder).setConnectError("5"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanCustomizerTest.java deleted file mode 100644 index 84beebc39..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanCustomizerTest.java +++ /dev/null @@ -1,133 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -import com.google.common.collect.Lists; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Vxlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetails; -import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.VxlanTunnelDump; - -public class VxlanCustomizerTest extends ReaderCustomizerTest { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IF_NAME = "ifc1"; - private static final int IF_INDEX = 0; - - private NamingContext interfacesContext; - static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(VppInterfaceStateAugmentation.class).child(Vxlan.class); - - public VxlanCustomizerTest() { - super(Vxlan.class, VppInterfaceStateAugmentationBuilder.class); - } - - @Override - public void setUp() throws UnknownHostException, VppInvocationException { - interfacesContext = new NamingContext("vxlan-tunnel", IFC_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - - final SwInterfaceDetails v = new SwInterfaceDetails(); - v.interfaceName = "vxlan-tunnel4".getBytes(); - final Map map = new HashMap<>(); - map.put(0, v); - cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, map); - - final VxlanTunnelDetailsReplyDump value = new VxlanTunnelDetailsReplyDump(); - final VxlanTunnelDetails vxlanTunnelDetails = new VxlanTunnelDetails(); - vxlanTunnelDetails.isIpv6 = 0; - vxlanTunnelDetails.decapNextIndex = 1; - vxlanTunnelDetails.dstAddress = InetAddress.getByName("1.2.3.4").getAddress(); - vxlanTunnelDetails.srcAddress = InetAddress.getByName("1.2.3.5").getAddress(); - vxlanTunnelDetails.encapVrfId = 55; - vxlanTunnelDetails.swIfIndex = 0; - vxlanTunnelDetails.vni = 9; - value.vxlanTunnelDetails = Lists.newArrayList(vxlanTunnelDetails); - doReturn(future(value)).when(api).vxlanTunnelDump(any(VxlanTunnelDump.class)); - } - - @Test - public void testReadCurrentAttributes() throws Exception { - final VxlanBuilder builder = getCustomizer().getBuilder(IID); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - - assertEquals(9, builder.getVni().getValue().intValue()); - assertEquals(55, builder.getEncapVrfId().intValue()); - - assertNull(builder.getSrc().getIpv6Address()); - assertNotNull(builder.getSrc().getIpv4Address()); - assertEquals("1.2.3.5", builder.getSrc().getIpv4Address().getValue()); - - assertNull(builder.getDst().getIpv6Address()); - assertNotNull(builder.getDst().getIpv4Address()); - assertEquals("1.2.3.4", builder.getDst().getIpv4Address().getValue()); - - verify(api).vxlanTunnelDump(any(VxlanTunnelDump.class)); - } - - @Test(expected = NullPointerException.class) - public void testReadCurrentAttributesVppNameNotCached() throws Exception { - InterfaceCustomizer.getCachedInterfaceDump(cache).remove(0); - - final VxlanBuilder builder = getCustomizer().getBuilder(IID); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - } - - @Test - public void testReadCurrentAttributesWrongType() throws Exception { - final SwInterfaceDetails v = new SwInterfaceDetails(); - v.interfaceName = "tap-2".getBytes(); - InterfaceCustomizer.getCachedInterfaceDump(cache).put(0, v); - - final VxlanBuilder builder = getCustomizer().getBuilder(IID); - getCustomizer().readCurrentAttributes(IID, builder, ctx); - - // Should be ignored - verifyZeroInteractions(api); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new VxlanCustomizer(api, interfacesContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java deleted file mode 100644 index e506ab361..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java +++ /dev/null @@ -1,278 +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.honeycomb.translate.v3po.interfacesstate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -import com.google.common.collect.Lists; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpe; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpeBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetails; -import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDump; - -public class VxlanGpeCustomizerTest extends ReaderCustomizerTest { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IF_NAME = "ifc2"; - private static final int IF_INDEX = 0; - - private NamingContext interfacesContext; - private static final InstanceIdentifier VXLAN_GPE_ID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(VppInterfaceStateAugmentation.class).child(VxlanGpe.class); - - public VxlanGpeCustomizerTest() { - super(VxlanGpe.class, VppInterfaceStateAugmentationBuilder.class); - } - - @Override - public void setUp() throws UnknownHostException, VppBaseCallException { - interfacesContext = new NamingContext("vxlan_gpe_inf", IFC_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - - final SwInterfaceDetails v = new SwInterfaceDetails(); - v.interfaceName = "vxlan_gpe_inf2".getBytes(); - final Map map = new HashMap<>(); - map.put(0, v); - cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, map); - - final VxlanGpeTunnelDetailsReplyDump value = new VxlanGpeTunnelDetailsReplyDump(); - final VxlanGpeTunnelDetails vxlanGpeTunnelDetails = new VxlanGpeTunnelDetails(); - vxlanGpeTunnelDetails.isIpv6 = 0; - vxlanGpeTunnelDetails.local = InetAddress.getByName("1.2.3.4").getAddress(); - vxlanGpeTunnelDetails.remote = InetAddress.getByName("1.2.3.5").getAddress(); - vxlanGpeTunnelDetails.vni = 9; - vxlanGpeTunnelDetails.protocol = 1; - vxlanGpeTunnelDetails.encapVrfId = 55; - vxlanGpeTunnelDetails.decapVrfId = 66; - vxlanGpeTunnelDetails.swIfIndex = 0; - value.vxlanGpeTunnelDetails = Lists.newArrayList(vxlanGpeTunnelDetails); - doReturn(future(value)).when(api).vxlanGpeTunnelDump(any(VxlanGpeTunnelDump.class)); - } - - @Test - public void testReadCurrentAttributes() throws Exception { - final VxlanGpeBuilder builder = getCustomizer().getBuilder(VXLAN_GPE_ID); - getCustomizer().readCurrentAttributes(VXLAN_GPE_ID, builder, ctx); - - assertNull(builder.getLocal().getIpv6Address()); - assertNotNull(builder.getLocal().getIpv4Address()); - assertEquals("1.2.3.4", builder.getLocal().getIpv4Address().getValue()); - - assertNull(builder.getRemote().getIpv6Address()); - assertNotNull(builder.getRemote().getIpv4Address()); - assertEquals("1.2.3.5", builder.getRemote().getIpv4Address().getValue()); - - assertEquals(9, builder.getVni().getValue().intValue()); - assertEquals(1, builder.getNextProtocol().getIntValue()); - assertEquals(55, builder.getEncapVrfId().intValue()); - assertEquals(66, builder.getDecapVrfId().intValue()); - - verify(api).vxlanGpeTunnelDump(any(VxlanGpeTunnelDump.class)); - } - - @Test(expected = NullPointerException.class) - public void testReadCurrentAttributesVppNameNotCached() throws Exception { - InterfaceCustomizer.getCachedInterfaceDump(cache).remove(0); - - final VxlanGpeBuilder builder = getCustomizer().getBuilder(VXLAN_GPE_ID); - getCustomizer().readCurrentAttributes(VXLAN_GPE_ID, builder, ctx); - } - - @Test - public void testReadCurrentAttributesWrongType() throws Exception { - final SwInterfaceDetails v = new SwInterfaceDetails(); - v.interfaceName = "tap-3".getBytes(); - InterfaceCustomizer.getCachedInterfaceDump(cache).put(0, v); - - final VxlanGpeBuilder builder = getCustomizer().getBuilder(VXLAN_GPE_ID); - getCustomizer().readCurrentAttributes(VXLAN_GPE_ID, builder, ctx); - - // Should be ignored - verifyZeroInteractions(api); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new VxlanGpeCustomizer(api, interfacesContext); - } -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java deleted file mode 100644 index b6dd44559..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/AclCustomizerTest.java +++ /dev/null @@ -1,99 +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.honeycomb.translate.v3po.interfacesstate.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class AclCustomizerTest extends ReaderCustomizerTest { - - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final int TABLE_INDEX = 123; - private static final String TABLE_NAME = "table123"; - private static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(VppInterfaceStateAugmentation.class).child(Acl.class).child(Ingress.class); - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - - private NamingContext interfaceContext; - - @Mock - private VppClassifierContextManager classifyTableContext; - - public AclCustomizerTest() { - super(Ingress.class, AclBuilder.class); - } - - @Override - public void setUp() { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new AclCustomizer(api, interfaceContext, classifyTableContext); - } - - @Test - public void testRead() throws ReadFailedException { - final IngressBuilder builder = mock(IngressBuilder.class); - - final ClassifyTableByInterfaceReply reply = new ClassifyTableByInterfaceReply(); - reply.l2TableId = TABLE_INDEX; - reply.ip4TableId = ~0; - reply.ip6TableId = ~0; - when(api.classifyTableByInterface(any())).thenReturn(future(reply)); - - when(classifyTableContext.getTableName(TABLE_INDEX, mappingContext)).thenReturn(TABLE_NAME); - - getCustomizer().readCurrentAttributes(IID, builder, ctx); - - verify(builder).setL2Acl(new L2AclBuilder().setClassifyTable(TABLE_NAME).build()); - verify(builder).setIp4Acl(null); - verify(builder).setIp6Acl(null); - } - - @Test(expected = ReadFailedException.class) - public void testReadFailed() throws ReadFailedException { - when(api.classifyTableByInterface(any())).thenReturn(failedFuture()); - getCustomizer().readCurrentAttributes(IID, mock(IngressBuilder.class), ctx); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java deleted file mode 100644 index 7406f94d7..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizerTest.java +++ /dev/null @@ -1,108 +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.honeycomb.translate.v3po.interfacesstate.acl.ingress; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceAclCustomizerTest extends ReaderCustomizerTest { - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUB_IF_NAME = "local0.1"; - private static final long SUB_IF_ID = 1; - private static final int SUB_IF_INDEX = 11; - private static final int TABLE_INDEX = 123; - private static final String TABLE_NAME = "table123"; - - private static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(SubinterfaceStateAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)).child(Acl.class).child(Ingress.class); - - private NamingContext interfaceContext; - - @Mock - private VppClassifierContextManager classifyTableContext; - - public SubInterfaceAclCustomizerTest() { - super(Ingress.class, AclBuilder.class); - } - - @Override - protected void setUp() throws Exception { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - defineMapping(mappingContext, SUB_IF_NAME, SUB_IF_INDEX, IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new SubInterfaceAclCustomizer(api, interfaceContext, classifyTableContext); - } - - @Test - public void testRead() throws ReadFailedException { - final IngressBuilder builder = mock(IngressBuilder.class); - - final ClassifyTableByInterfaceReply reply = new ClassifyTableByInterfaceReply(); - reply.swIfIndex = SUB_IF_INDEX; - reply.l2TableId = ~0; - reply.ip4TableId = TABLE_INDEX; - reply.ip6TableId = TABLE_INDEX; - when(api.classifyTableByInterface(any())).thenReturn(future(reply)); - - when(classifyTableContext.getTableName(TABLE_INDEX, mappingContext)).thenReturn(TABLE_NAME); - - getCustomizer().readCurrentAttributes(IID, builder, ctx); - - verify(builder).setL2Acl(null); - verify(builder).setIp4Acl(new Ip4AclBuilder().setClassifyTable(TABLE_NAME).build()); - verify(builder).setIp6Acl(new Ip6AclBuilder().setClassifyTable(TABLE_NAME).build()); - } - - @Test(expected = ReadFailedException.class) - public void testReadFailed() throws ReadFailedException { - when(api.classifyTableByInterface(any())).thenReturn(failedFuture()); - getCustomizer().readCurrentAttributes(IID, mock(IngressBuilder.class), ctx); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java deleted file mode 100644 index efe6c6afe..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java +++ /dev/null @@ -1,284 +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.honeycomb.translate.v3po.interfacesstate.ip; - - -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.util.read.cache.CacheKeyFactory; -import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; -import io.fd.honeycomb.translate.vpp.util.Ipv4Translator; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; -import io.fd.vpp.jvpp.core.dto.IpAddressDetails; -import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.IpAddressDump; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; -import org.hamcrest.Matchers; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLength; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest implements - Ipv4Translator { - - private static final String IFACE_NAME = "eth0"; - private static final String IFACE_2_NAME = "eth1"; - private static final int IFACE_ID = 1; - private static final int IFACE_2_ID = 2; - private static final String IFC_CTX_NAME = "ifc-test-instance"; - - private NamingContext interfacesContext; - private InstanceIdentifier
ifaceOneAddressOneIdentifier; - private InstanceIdentifier
ifaceTwoAddressOneIdentifier; - private CacheKeyFactory cacheKeyFactory; - - public Ipv4AddressCustomizerTest() { - super(Address.class, Ipv4Builder.class); - } - - @Override - public void setUp() { - interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - defineMapping(mappingContext, IFACE_2_NAME, IFACE_2_ID, IFC_CTX_NAME); - - ifaceOneAddressOneIdentifier = - InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(IFACE_NAME)) - .augmentation(Interface2.class) - .child(Ipv4.class) - .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); - ifaceTwoAddressOneIdentifier = - InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(IFACE_2_NAME)) - .augmentation(Interface2.class) - .child(Ipv4.class) - .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); - - // to simulate complex key - cacheKeyFactory = new IdentifierCacheKeyFactory(ImmutableSet.of(Interface.class)); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new Ipv4AddressCustomizer(api, interfacesContext); - } - - private static InstanceIdentifier
getId(final String address, final String ifaceName) { - return InstanceIdentifier.builder(InterfacesState.class) - .child(Interface.class, new InterfaceKey(ifaceName)) - .augmentation(Interface2.class) - .child(Ipv4.class) - .child(Address.class, new AddressKey(new Ipv4AddressNoZone(new Ipv4Address(address)))) - .build(); - } - - @Test - public void testReadCurrentAttributesFor2Ifcs() throws ReadFailedException { - //changed to mock to not store first dumped data(otherwise that double thenReturn on line 118 is not gonna work) - - IpAddressDetails detail1 = new IpAddressDetails(); - IpAddressDetails detail2 = new IpAddressDetails(); - - detail1.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); - detail2.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.2")))); - - IpAddressDetailsReplyDump reply = new IpAddressDetailsReplyDump(); - reply.ipAddressDetails = ImmutableList.of(detail1); - IpAddressDetailsReplyDump reply2 = new IpAddressDetailsReplyDump(); - reply2.ipAddressDetails = ImmutableList.of(detail2); - - CompletableFuture future = new CompletableFuture<>(); - future.complete(reply); - CompletableFuture future2 = new CompletableFuture<>(); - future2.complete(reply2); - - when(api.ipAddressDump(Mockito.any(IpAddressDump.class))).thenReturn(future).thenReturn(future2) - .thenReturn(future).thenReturn(future2); - when(api.ipAddressDump(Mockito.any(IpAddressDump.class))).thenReturn(future(reply)).thenReturn(future(reply2)) - .thenReturn(future(reply)).thenReturn(future(reply2)); - when(ctx.getModificationCache()).thenReturn(cache); - - - final InstanceIdentifier
id = getId("192.168.2.1", IFACE_NAME); - final InstanceIdentifier
id2 = getId("192.168.2.2", IFACE_2_NAME); - - final List ifc1Ids = getCustomizer().getAllIds(id, ctx); - assertThat(ifc1Ids.size(), is(1)); - assertThat(ifc1Ids, Matchers.hasItem(new AddressKey(new Ipv4AddressNoZone("192.168.2.1")))); - final List ifc2Ids = getCustomizer().getAllIds(id2, ctx); - assertThat(ifc2Ids.size(), is(1)); - assertThat(ifc2Ids, Matchers.hasItem(new AddressKey(new Ipv4AddressNoZone("192.168.2.2")))); - - AddressBuilder builder = new AddressBuilder(); - getCustomizer().readCurrentAttributes(id, builder, ctx); - assertEquals(builder.getIp().getValue(), "192.168.2.1"); - builder = new AddressBuilder(); - getCustomizer().readCurrentAttributes(id2, builder, ctx); - assertEquals(builder.getIp().getValue(), "192.168.2.2"); - } - - @Test - public void testReadCurrentAttributesSuccessfull() throws ReadFailedException { - IpAddressDetails detail1 = new IpAddressDetails(); - IpAddressDetails detail2 = new IpAddressDetails(); - IpAddressDetails detail3 = new IpAddressDetails(); - - detail1.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); - detail2.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.2")))); - detail3.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.3")))); - - IpAddressDetailsReplyDump reply = new IpAddressDetailsReplyDump(); - reply.ipAddressDetails = ImmutableList.of(detail1, detail2, detail3); - when(api.ipAddressDump(Mockito.any(IpAddressDump.class))).thenReturn(future(reply)); - when(ctx.getModificationCache()).thenReturn(cache); - - final AddressBuilder builder = new AddressBuilder(); - final InstanceIdentifier
id = getId("192.168.2.1", IFACE_NAME); - - getCustomizer().readCurrentAttributes(id, builder, ctx); - - assertEquals("192.168.2.1", builder.getIp().getValue()); - } - - @Test - public void testGetAllIdsFromSuccessfull() throws ReadFailedException { - IpAddressDetails detail1 = new IpAddressDetails(); - IpAddressDetails detail2 = new IpAddressDetails(); - IpAddressDetails detail3 = new IpAddressDetails(); - - detail1.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); - detail2.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.2")))); - detail3.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.3")))); - - IpAddressDetailsReplyDump reply = new IpAddressDetailsReplyDump(); - reply.ipAddressDetails = ImmutableList.of(detail1, detail2, detail3); - when(api.ipAddressDump(Mockito.any(IpAddressDump.class))).thenReturn(future(reply)); - when(ctx.getModificationCache()).thenReturn(cache); - - final InstanceIdentifier
id = getId("192.168.2.1", IFACE_NAME); - - List ids = getCustomizer().getAllIds(id, ctx).stream() - .map(key -> key.getIp()) - .collect(Collectors.toList()); - - assertEquals(3, ids.size()); - assertEquals(true, "192.168.2.1".equals(ids.get(0).getValue())); - assertEquals(true, "192.168.2.2".equals(ids.get(1).getValue())); - assertEquals(true, "192.168.2.3".equals(ids.get(2).getValue())); - } - - @Test - public void testCachingScopeSpecificRequest() throws ReadFailedException { - fillCacheForTwoIfaces(); - final AddressBuilder ifaceOneAddressBuilder = new AddressBuilder(); - final AddressBuilder ifaceTwoAddressBuilder = new AddressBuilder(); - - getCustomizer().readCurrentAttributes(ifaceOneAddressOneIdentifier, ifaceOneAddressBuilder, ctx); - getCustomizer().readCurrentAttributes(ifaceTwoAddressOneIdentifier, ifaceTwoAddressBuilder, ctx); - - // addresses have caching scope of parent interface, so returned address should have respective prefix lengths - assertEquals("192.168.2.1", ifaceOneAddressBuilder.getIp().getValue()); - assertTrue(ifaceOneAddressBuilder.getSubnet() instanceof PrefixLength); - assertEquals(22, PrefixLength.class.cast(ifaceOneAddressBuilder.getSubnet()).getPrefixLength().intValue()); - - assertEquals("192.168.2.1", ifaceTwoAddressBuilder.getIp().getValue()); - assertTrue(ifaceTwoAddressBuilder.getSubnet() instanceof PrefixLength); - assertEquals(23, PrefixLength.class.cast(ifaceTwoAddressBuilder.getSubnet()).getPrefixLength().intValue()); - } - - @Test - public void testCachingScopeGetAll() throws ReadFailedException { - fillCacheForFirstIfaceSecondEmpty(); - - final List keysForIfaceOne = getCustomizer().getAllIds(ifaceOneAddressOneIdentifier, ctx); - assertThat(keysForIfaceOne, hasSize(1)); - final AddressKey keyIfaceOne = keysForIfaceOne.get(0); - assertEquals("192.168.2.1", keyIfaceOne.getIp().getValue()); - - final List keysForIfaceTwo = getCustomizer().getAllIds(ifaceTwoAddressOneIdentifier, ctx); - assertThat(keysForIfaceTwo, is(empty())); - } - - private void fillCacheForTwoIfaces() { - IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); - IpAddressDetails detailIfaceTwoAddressOne = new IpAddressDetails(); - IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); - IpAddressDetailsReplyDump replyIfaceTwo = new IpAddressDetailsReplyDump(); - - replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); - replyIfaceTwo.ipAddressDetails = Arrays.asList(detailIfaceTwoAddressOne); - - detailIfaceOneAddressOne.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); - detailIfaceOneAddressOne.prefixLength = 22; - - detailIfaceTwoAddressOne.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); - detailIfaceTwoAddressOne.prefixLength = 23; - - cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); - cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), replyIfaceTwo); - } - - private void fillCacheForFirstIfaceSecondEmpty() { - IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); - IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); - replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); - - detailIfaceOneAddressOne.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); - detailIfaceOneAddressOne.prefixLength = 22; - - cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); - cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), new IpAddressDetailsReplyDump()); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4CustomizerTest.java deleted file mode 100644 index f536a37eb..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4CustomizerTest.java +++ /dev/null @@ -1,44 +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.honeycomb.translate.v3po.interfacesstate.ip; - -import static org.mockito.Mockito.verifyZeroInteractions; - -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; - -public class Ipv4CustomizerTest extends ReaderCustomizerTest { - - public Ipv4CustomizerTest() { - super(Ipv4.class, Interface2Builder.class); - } - - @Test - public void testReadCurrentAttributes() throws Exception { - customizer.readCurrentAttributes(null, null, ctx); - verifyZeroInteractions(api); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new Ipv4Customizer(api); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java deleted file mode 100644 index 9a9346a5a..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java +++ /dev/null @@ -1,247 +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.honeycomb.translate.v3po.interfacesstate.ip; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.collect.ImmutableSet; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; -import io.fd.honeycomb.translate.util.read.cache.CacheKeyFactory; -import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; -import io.fd.honeycomb.translate.vpp.util.Ipv4Translator; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; -import io.fd.vpp.jvpp.core.dto.IpAddressDetails; -import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; -import java.util.Arrays; -import java.util.List; -import org.junit.Assert; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class SubInterfaceIpv4AddressCustomizerTest extends ListReaderCustomizerTest - implements Ipv4Translator { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IF_NAME = "local0"; - private static final int IF_INDEX = 1; - private static final String SUB_IF_NAME = "local0.1"; - private static final String SUB_IF_2_NAME = "local0.2"; - private static final long SUB_IF_ID = 1; - private static final int SUB_IF_INDEX = 11; - private static final int SUB_IF_2_INDEX = 12; - private static final InstanceIdentifier IP4_IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(SubinterfaceStateAugmentation.class) - .child(SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)) - .child(Ipv4.class); - private InstanceIdentifier
ifaceOneAddressOneIdentifier; - private InstanceIdentifier
ifaceTwoAddressOneIdentifier; - private CacheKeyFactory cacheKeyFactory; - private static final Ipv4AddressNoZone IP1 = new Ipv4AddressNoZone("10.1.1.1"); - private static final Ipv4AddressNoZone IP2 = new Ipv4AddressNoZone("10.1.1.2"); - private static final short PREFIX_LENGTH = 16; - - private NamingContext interfaceContext; - - public SubInterfaceIpv4AddressCustomizerTest() { - super(Address.class, Ipv4Builder.class); - } - - @Override - protected void setUp() throws Exception { - interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - - ifaceOneAddressOneIdentifier = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(SubinterfaceStateAugmentation.class) - .child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(1L)) - .child(Ipv4.class) - .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); - ifaceTwoAddressOneIdentifier = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(SubinterfaceStateAugmentation.class) - .child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(2L)) - .child(Ipv4.class) - .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); - - // to simulate complex key - cacheKeyFactory = new IdentifierCacheKeyFactory(ImmutableSet.of(SubInterface.class)); - - defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); - defineMapping(mappingContext, SUB_IF_NAME, SUB_IF_INDEX, IFC_CTX_NAME); - defineMapping(mappingContext, SUB_IF_2_NAME, SUB_IF_2_INDEX, IFC_CTX_NAME); - } - - @Override - protected ListReaderCustomizer initCustomizer() { - return new SubInterfaceIpv4AddressCustomizer(api, interfaceContext); - } - - private static InstanceIdentifier
getId() { - return IP4_IID.child(Address.class); - } - - private static InstanceIdentifier
getId(final Ipv4AddressNoZone ip) { - return IP4_IID.child(Address.class, new AddressKey(ip)); - } - - @Test - public void testRead() throws ReadFailedException { - final AddressBuilder builder = mock(AddressBuilder.class); - when(api.ipAddressDump(any())).thenReturn(future(dump())); - getCustomizer().readCurrentAttributes(getId(IP2), builder, ctx); - verify(builder).setIp(IP2); - verify(builder).setSubnet(new PrefixLengthBuilder().setPrefixLength(PREFIX_LENGTH).build()); - } - - @Test(expected = ReadFailedException.class) - public void testReadFailed() throws ReadFailedException { - when(api.ipAddressDump(any())).thenReturn(failedFuture()); - getCustomizer().readCurrentAttributes(getId(IP1), mock(AddressBuilder.class), ctx); - } - - @Test - public void testGetAllIds() throws ReadFailedException { - when(api.ipAddressDump(any())).thenReturn(future(dump())); - final List allIds = getCustomizer().getAllIds(getId(), ctx); - assertThat(allIds, hasSize(2)); - assertThat(allIds, containsInAnyOrder(new AddressKey(IP1), new AddressKey(IP2))); - } - - @Test(expected = ReadFailedException.class) - public void testGetAllIdsFailed() throws ReadFailedException { - when(api.ipAddressDump(any())).thenReturn(failedFuture()); - getCustomizer().getAllIds(getId(), ctx); - } - - @Test - public void testCacheScope() { - - } - - @Test - public void testCachingScopeSpecificRequest() throws ReadFailedException { - fillCacheForTwoIfaces(); - final AddressBuilder ifaceOneAddressBuilder = new AddressBuilder(); - final AddressBuilder ifaceTwoAddressBuilder = new AddressBuilder(); - - getCustomizer().readCurrentAttributes(ifaceOneAddressOneIdentifier, ifaceOneAddressBuilder, ctx); - getCustomizer().readCurrentAttributes(ifaceTwoAddressOneIdentifier, ifaceTwoAddressBuilder, ctx); - - // addresses have caching scope of parent interface, so returned address should have respective prefix lengths - assertEquals("192.168.2.1", ifaceOneAddressBuilder.getIp().getValue()); - assertTrue(ifaceOneAddressBuilder.getSubnet() instanceof PrefixLength); - assertEquals(22, PrefixLength.class.cast(ifaceOneAddressBuilder.getSubnet()).getPrefixLength().intValue()); - - assertEquals("192.168.2.1", ifaceTwoAddressBuilder.getIp().getValue()); - assertTrue(ifaceTwoAddressBuilder.getSubnet() instanceof PrefixLength); - assertEquals(23, PrefixLength.class.cast(ifaceTwoAddressBuilder.getSubnet()).getPrefixLength().intValue()); - } - - @Test - public void testCachingScopeGetAll() throws ReadFailedException { - fillCacheForFirstIfaceSecondEmpty(); - - final List keysForIfaceOne = getCustomizer().getAllIds(ifaceOneAddressOneIdentifier, ctx); - Assert.assertThat(keysForIfaceOne, hasSize(1)); - final AddressKey keyIfaceOne = keysForIfaceOne.get(0); - assertEquals("192.168.2.1", keyIfaceOne.getIp().getValue()); - - final List keysForIfaceTwo = getCustomizer().getAllIds(ifaceTwoAddressOneIdentifier, ctx); - Assert.assertThat(keysForIfaceTwo, is(empty())); - } - - private void fillCacheForTwoIfaces() { - IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); - IpAddressDetails detailIfaceTwoAddressOne = new IpAddressDetails(); - IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); - IpAddressDetailsReplyDump replyIfaceTwo = new IpAddressDetailsReplyDump(); - - replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); - replyIfaceTwo.ipAddressDetails = Arrays.asList(detailIfaceTwoAddressOne); - - detailIfaceOneAddressOne.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); - detailIfaceOneAddressOne.prefixLength = 22; - - detailIfaceTwoAddressOne.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); - detailIfaceTwoAddressOne.prefixLength = 23; - - cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); - cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), replyIfaceTwo); - } - - private void fillCacheForFirstIfaceSecondEmpty() { - IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); - IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); - replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); - - detailIfaceOneAddressOne.ip = reverseBytes( - ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); - detailIfaceOneAddressOne.prefixLength = 22; - - cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); - cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), new IpAddressDetailsReplyDump()); - } - - private IpAddressDetailsReplyDump dump() { - final IpAddressDetailsReplyDump reply = new IpAddressDetailsReplyDump(); - - final IpAddressDetails details1 = new IpAddressDetails(); - details1.ip = new byte[]{1, 1, 1, 10}; - details1.prefixLength = (byte) PREFIX_LENGTH; - reply.ipAddressDetails.add(details1); - - final IpAddressDetails details2 = new IpAddressDetails(); - details2.ip = new byte[]{2, 1, 1, 10}; - details2.prefixLength = (byte) PREFIX_LENGTH; - reply.ipAddressDetails.add(details2); - - return reply; - } -} \ No newline at end of file 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 deleted file mode 100644 index 156e9a055..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java +++ /dev/null @@ -1,35 +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.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.rev161214.PbbRewriteStateInterfaceAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteStateBuilder; - -public class PbbRewriteStateCustomizerTest extends ReaderCustomizerTest { - - public PbbRewriteStateCustomizerTest() { - super(PbbRewriteState.class, PbbRewriteStateInterfaceAugmentationBuilder.class); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new PbbRewriteStateCustomizer(api); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/notification/InterfaceChangeNotificationProducerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/notification/InterfaceChangeNotificationProducerTest.java deleted file mode 100644 index 40ae35700..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/notification/InterfaceChangeNotificationProducerTest.java +++ /dev/null @@ -1,112 +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.honeycomb.translate.v3po.notification; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import io.fd.honeycomb.notification.NotificationCollector; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.vpp.test.util.NamingContextHelper; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.util.FutureProducer; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStateChange; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.InterfaceStatus; -import io.fd.vpp.jvpp.core.callback.SwInterfaceSetFlagsNotificationCallback; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsNotification; -import io.fd.vpp.jvpp.core.dto.WantInterfaceEvents; -import io.fd.vpp.jvpp.core.dto.WantInterfaceEventsReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import io.fd.vpp.jvpp.core.notification.CoreNotificationRegistry; - -public class InterfaceChangeNotificationProducerTest implements FutureProducer, NamingContextHelper { - - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private static final String IFACE_NAME = "eth0"; - private static final int IFACE_ID = 0; - - @Mock - private FutureJVppCore jVpp; - private NamingContext namingContext = new NamingContext("test", IFC_CTX_NAME); - @Mock - private MappingContext mappingContext; - @Mock - private NotificationCollector collector; - @Mock - private CoreNotificationRegistry notificationRegistry; - @Mock - private AutoCloseable notificationListenerReg; - - private ArgumentCaptor callbackArgumentCaptor; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - doReturn(notificationRegistry).when(jVpp).getNotificationRegistry(); - callbackArgumentCaptor = ArgumentCaptor.forClass(SwInterfaceSetFlagsNotificationCallback.class); - doReturn(notificationListenerReg).when(notificationRegistry).registerSwInterfaceSetFlagsNotificationCallback( - callbackArgumentCaptor.capture()); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - doReturn(future(new WantInterfaceEventsReply())).when(jVpp).wantInterfaceEvents(any(WantInterfaceEvents.class)); - } - - @Test - public void testStart() throws Exception { - final InterfaceChangeNotificationProducer interfaceChangeNotificationProducer = - new InterfaceChangeNotificationProducer(jVpp, namingContext, mappingContext); - - interfaceChangeNotificationProducer.start(collector); - verify(jVpp).wantInterfaceEvents(any(WantInterfaceEvents.class)); - verify(jVpp).getNotificationRegistry(); - verify(notificationRegistry).registerSwInterfaceSetFlagsNotificationCallback(any( - SwInterfaceSetFlagsNotificationCallback.class)); - - interfaceChangeNotificationProducer.stop(); - verify(jVpp, times(2)).wantInterfaceEvents(any(WantInterfaceEvents.class)); - verify(notificationListenerReg).close(); - } - - @Test - public void testNotification() throws Exception { - final InterfaceChangeNotificationProducer interfaceChangeNotificationProducer = - new InterfaceChangeNotificationProducer(jVpp, namingContext, mappingContext); - - interfaceChangeNotificationProducer.start(collector); - - final SwInterfaceSetFlagsNotification swInterfaceSetFlagsNotification = new SwInterfaceSetFlagsNotification(); - swInterfaceSetFlagsNotification.deleted = 0; - swInterfaceSetFlagsNotification.swIfIndex = IFACE_ID; - swInterfaceSetFlagsNotification.adminUpDown = 1; - swInterfaceSetFlagsNotification.linkUpDown = 1; - callbackArgumentCaptor.getValue().onSwInterfaceSetFlagsNotification(swInterfaceSetFlagsNotification); - final ArgumentCaptor notificationCaptor = - ArgumentCaptor.forClass(InterfaceStateChange.class); - verify(collector).onNotification(notificationCaptor.capture()); - - assertEquals(IFACE_NAME, notificationCaptor.getValue().getName().getString()); - assertEquals(InterfaceStatus.Up, notificationCaptor.getValue().getAdminStatus()); - assertEquals(InterfaceStatus.Up, notificationCaptor.getValue().getOperStatus()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/ArpTerminationTableEntryCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/ArpTerminationTableEntryCustomizerTest.java deleted file mode 100644 index 95000c029..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/ArpTerminationTableEntryCustomizerTest.java +++ /dev/null @@ -1,171 +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.honeycomb.translate.v3po.vpp; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -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.VppBaseCallException; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.BdIpMacAddDel; -import io.fd.vpp.jvpp.core.dto.BdIpMacAddDelReply; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.ArpTerminationTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class ArpTerminationTableEntryCustomizerTest extends WriterCustomizerTest { - private static final String BD_CTX_NAME = "bd-test-instance"; - private static final String IFC_CTX_NAME = "ifc-test-instance"; - - private static final String BD_NAME = "testBD0"; - private static final int BD_ID = 111; - private static final String IFACE_NAME = "eth0"; - private static final int IFACE_ID = 123; - private ArpTerminationTableEntryCustomizer customizer; - private byte[] ipAddressRaw; - private byte[] physAddressRaw; - private PhysAddress physAddress; - private IpAddress ipAddress; - private ArpTerminationTableEntry entry; - private InstanceIdentifier id; - - @Override - public void setUp() throws Exception { - customizer = new ArpTerminationTableEntryCustomizer(api, new NamingContext("generatedBdName", BD_CTX_NAME)); - - ipAddressRaw = new byte[]{1, 2, 3, 4}; - physAddressRaw = new byte[]{1, 2, 3, 4, 5, 6}; - physAddress = new PhysAddress("01:02:03:04:05:06"); - - ipAddress = new IpAddress(Ipv4AddressNoZone.getDefaultInstance("1.2.3.4")); - entry = generateArpEntry(ipAddress, physAddress); - id = getArpEntryId(ipAddress, physAddress); - - defineMapping(mappingContext, BD_NAME, BD_ID, BD_CTX_NAME); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - } - - private static InstanceIdentifier getArpEntryId(final IpAddress ipAddress, - final PhysAddress physAddress) { - return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(BD_NAME)) - .child(ArpTerminationTable.class) - .child(ArpTerminationTableEntry.class, new ArpTerminationTableEntryKey(ipAddress, physAddress)); - } - - private void whenBdIpMacAddDelThenSuccess() { - doReturn(future(new BdIpMacAddDelReply())).when(api).bdIpMacAddDel(any(BdIpMacAddDel.class)); - } - - private void whenBdIpMacAddDelThenFailure() { - doReturn(failedFuture()).when(api).bdIpMacAddDel(any(BdIpMacAddDel.class)); - } - - private BdIpMacAddDel generateBdIpMacAddDelRequest(final byte[] ipAddress, final byte[] macAddress, - final byte isAdd) { - final BdIpMacAddDel request = new BdIpMacAddDel(); - request.ipAddress = ipAddress; - request.macAddress = macAddress; - request.bdId = BD_ID; - request.isAdd = isAdd; - return request; - } - - private ArpTerminationTableEntry generateArpEntry(final IpAddress ipAddress, final PhysAddress physAddress) { - final ArpTerminationTableEntryBuilder entry = new ArpTerminationTableEntryBuilder(); - entry.setKey(new ArpTerminationTableEntryKey(ipAddress, physAddress)); - entry.setPhysAddress(physAddress); - entry.setIpAddress(ipAddress); - return entry.build(); - } - - private void verifyBdIpMacAddDelWasInvoked(final BdIpMacAddDel expected) throws - VppInvocationException { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(BdIpMacAddDel.class); - verify(api).bdIpMacAddDel(argumentCaptor.capture()); - final BdIpMacAddDel actual = argumentCaptor.getValue(); - assertArrayEquals(expected.macAddress, actual.macAddress); - assertArrayEquals(expected.ipAddress, actual.ipAddress); - assertEquals(expected.bdId, actual.bdId); - assertEquals(expected.isAdd, actual.isAdd); - } - - @Test - public void testCreate() throws Exception { - whenBdIpMacAddDelThenSuccess(); - customizer.writeCurrentAttributes(id, entry, writeContext); - verifyBdIpMacAddDelWasInvoked(generateBdIpMacAddDelRequest(ipAddressRaw, physAddressRaw, (byte) 1)); - } - - @Test - public void testCreateFailed() throws Exception { - whenBdIpMacAddDelThenFailure(); - try { - customizer.writeCurrentAttributes(id, entry, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyBdIpMacAddDelWasInvoked(generateBdIpMacAddDelRequest(ipAddressRaw, physAddressRaw, (byte) 1)); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test(expected = UnsupportedOperationException.class) - public void testUpdate() throws Exception { - customizer.updateCurrentAttributes(InstanceIdentifier.create(ArpTerminationTableEntry.class), - mock(ArpTerminationTableEntry.class), - mock(ArpTerminationTableEntry.class), writeContext); - } - - @Test - public void testDelete() throws Exception { - whenBdIpMacAddDelThenSuccess(); - customizer.deleteCurrentAttributes(id, entry, writeContext); - verifyBdIpMacAddDelWasInvoked(generateBdIpMacAddDelRequest(ipAddressRaw, physAddressRaw, (byte) 0)); - } - - @Test - public void testDeleteFailed() throws Exception { - whenBdIpMacAddDelThenFailure(); - try { - customizer.deleteCurrentAttributes(id, entry, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyBdIpMacAddDelWasInvoked(generateBdIpMacAddDelRequest(ipAddressRaw, physAddressRaw, (byte) 0)); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/BridgeDomainCustomizerTest.java deleted file mode 100644 index 9143080fe..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/BridgeDomainCustomizerTest.java +++ /dev/null @@ -1,276 +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.honeycomb.translate.v3po.vpp; - -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; -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.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDel; -import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDelReply; -import javax.annotation.Nullable; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; - -public class BridgeDomainCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { - - private static final String BD_CTX_NAME = "bd-test-instance"; - private static final byte ADD_OR_UPDATE_BD = (byte) 1; - private BridgeDomainCustomizer customizer; - - @Override - public void setUp() throws Exception { - customizer = new BridgeDomainCustomizer(api, new NamingContext("generatedBDName", BD_CTX_NAME)); - } - - @Nullable - private static Boolean intToBoolean(final int value) { - if (value == 0) { - return Boolean.FALSE; - } - if (value == 1) { - return Boolean.TRUE; - } - return null; - } - - private static KeyedInstanceIdentifier bdIdentifierForName( - final String bdName) { - return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(bdName)); - } - - private BridgeDomain generateBridgeDomain(final String bdName) { - final byte arpTerm = 0; - final byte flood = 1; - final byte forward = 0; - final byte learn = 1; - final byte uuf = 0; - return generateBridgeDomain(bdName, arpTerm, flood, forward, learn, uuf); - } - - private BridgeDomain generateBridgeDomain(final String bdName, final int arpTerm, final int flood, - final int forward, final int learn, final int uuf) { - return new BridgeDomainBuilder() - .setName(bdName) - .setArpTermination(intToBoolean(arpTerm)) - .setFlood(intToBoolean(flood)) - .setForward(intToBoolean(forward)) - .setLearn(intToBoolean(learn)) - .setUnknownUnicastFlood(intToBoolean(uuf)) - .build(); - } - - private void verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd, final int bdId) - throws VppInvocationException { - final BridgeDomainAddDel expected = new BridgeDomainAddDel(); - expected.arpTerm = booleanToByte(bd.isArpTermination()); - expected.flood = booleanToByte(bd.isFlood()); - expected.forward = booleanToByte(bd.isForward()); - expected.learn = booleanToByte(bd.isLearn()); - expected.uuFlood = booleanToByte(bd.isUnknownUnicastFlood()); - expected.isAdd = ADD_OR_UPDATE_BD; - expected.bdId = bdId; - verify(api).bridgeDomainAddDel(expected); - } - - private void verifyBridgeDomainDeleteWasInvoked(final int bdId) throws VppInvocationException { - final BridgeDomainAddDel expected = new BridgeDomainAddDel(); - expected.bdId = bdId; - verify(api).bridgeDomainAddDel(expected); - } - - private void whenBridgeDomainAddDelThenSuccess() { - when(api.bridgeDomainAddDel(any(BridgeDomainAddDel.class))).thenReturn(future(new BridgeDomainAddDelReply())); - } - - private void whenBridgeDomainAddDelThenFailure() { - doReturn(failedFuture()).when(api).bridgeDomainAddDel(any(BridgeDomainAddDel.class)); - } - - @Test - public void testAddBridgeDomain() throws Exception { - final int bdId = 1; - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain(bdName); - noMappingDefined(mappingContext, bdName, BD_CTX_NAME); - - whenBridgeDomainAddDelThenSuccess(); - - customizer.writeCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); - - verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId); - verify(mappingContext).put(mappingIid(bdName, BD_CTX_NAME), mapping(bdName, bdId).get()); - } - - @Test - public void testAddBridgeDomainPresentInBdContext() throws Exception { - final int bdId = 1; - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain(bdName); - defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); - - whenBridgeDomainAddDelThenSuccess(); - - customizer.writeCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); - - verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId); - verify(mappingContext).put(mappingIid(bdName, BD_CTX_NAME), mapping(bdName, bdId).get()); - } - - @Test - public void testAddBridgeDomainFailed() throws Exception { - final int bdId = 1; - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain(bdName); - noMappingDefined(mappingContext, bdName, BD_CTX_NAME); - - whenBridgeDomainAddDelThenFailure(); - - try { - customizer.writeCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); - } catch (WriteFailedException e) { - verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testDeleteBridgeDomain() throws Exception { - final int bdId = 1; - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain(bdName); - defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); - - whenBridgeDomainAddDelThenSuccess(); - - customizer.deleteCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); - - verifyBridgeDomainDeleteWasInvoked(bdId); - } - - @Test - public void testDeleteUnknownBridgeDomain() throws Exception { - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain("bd1"); - noMappingDefined(mappingContext, bdName, BD_CTX_NAME); - - try { - customizer.deleteCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); - } catch (IllegalArgumentException e) { - verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class)); - return; - } - fail("IllegalArgumentException was expected"); - } - - @Test - public void testDeleteBridgeDomainFailed() throws Exception { - final int bdId = 1; - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain(bdName); - defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); - - whenBridgeDomainAddDelThenFailure(); - - try { - customizer.deleteCurrentAttributes(bdIdentifierForName(bdName), bd, writeContext); - } catch (WriteFailedException e) { - verifyBridgeDomainDeleteWasInvoked(bdId); - return; - } - - fail("WriteFailedException.DeleteFailedException was expected"); - } - - @Test - public void testUpdateBridgeDomain() throws Exception { - final int bdId = 1; - final String bdName = "bd1"; - defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); - - final byte arpTermBefore = 1; - final byte floodBefore = 1; - final byte forwardBefore = 0; - final byte learnBefore = 1; - final byte uufBefore = 0; - - final BridgeDomain dataBefore = - generateBridgeDomain(bdName, arpTermBefore, floodBefore, forwardBefore, learnBefore, uufBefore); - final BridgeDomain dataAfter = - generateBridgeDomain(bdName, arpTermBefore ^ 1, floodBefore ^ 1, forwardBefore ^ 1, learnBefore ^ 1, - uufBefore ^ 1); - - whenBridgeDomainAddDelThenSuccess(); - - customizer - .updateCurrentAttributes(bdIdentifierForName(bdName), dataBefore, dataAfter, - writeContext); - verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter, bdId); - } - - @Test - public void testUpdateUnknownBridgeDomain() throws Exception { - final String bdName = "bd1"; - final BridgeDomain bdBefore = generateBridgeDomain(bdName, 0, 1, 0, 1, 0); - final BridgeDomain bdAfter = generateBridgeDomain(bdName, 1, 1, 0, 1, 0); - noMappingDefined(mappingContext, bdName, BD_CTX_NAME); - - try { - customizer - .updateCurrentAttributes(bdIdentifierForName(bdName), bdBefore, bdAfter, - writeContext); - } catch (IllegalArgumentException e) { - verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class)); - return; - } - fail("IllegalArgumentException was expected"); - } - - @Test - public void testUpdateBridgeDomainFailed() throws Exception { - final int bdId = 1; - final String bdName = "bd1"; - final BridgeDomain bdBefore = generateBridgeDomain(bdName, 0, 1, 0, 1, 0); - final BridgeDomain bdAfter = generateBridgeDomain(bdName, 1, 1, 0, 1, 0); - defineMapping(mappingContext, bdName, bdId, BD_CTX_NAME); - - whenBridgeDomainAddDelThenFailure(); - - try { - customizer.updateCurrentAttributes(bdIdentifierForName(bdName), bdBefore, bdAfter, writeContext); - } catch (WriteFailedException e) { - verifyBridgeDomainAddOrUpdateWasInvoked(bdAfter, bdId); - return; - } - fail("IllegalStateException was expected"); - } - -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/L2FibEntryCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/L2FibEntryCustomizerTest.java deleted file mode 100644 index 88e75a7ac..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vpp/L2FibEntryCustomizerTest.java +++ /dev/null @@ -1,190 +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.honeycomb.translate.v3po.vpp; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -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.VppBaseCallException; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.L2FibAddDel; -import io.fd.vpp.jvpp.core.dto.L2FibAddDelReply; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class L2FibEntryCustomizerTest extends WriterCustomizerTest { - private static final String BD_CTX_NAME = "bd-test-instance"; - private static final String IFC_CTX_NAME = "ifc-test-instance"; - - private static final String BD_NAME = "testBD0"; - private static final int BD_ID = 111; - private static final String IFACE_NAME = "eth0"; - private static final int IFACE_ID = 123; - - private L2FibEntryCustomizer customizer; - - @Override - public void setUp() throws Exception { - defineMapping(mappingContext, BD_NAME, BD_ID, BD_CTX_NAME); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - - customizer = new L2FibEntryCustomizer( - api, - new NamingContext("generatedBdName", BD_CTX_NAME), - new NamingContext("generatedIfaceName", IFC_CTX_NAME)); - } - - private static InstanceIdentifier getL2FibEntryId(final PhysAddress address) { - return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(BD_NAME)) - .child(L2FibTable.class).child(L2FibEntry.class, new L2FibEntryKey(address)); - } - - private void whenL2FibAddDelThenSuccess() { - doReturn(future(new L2FibAddDelReply())).when(api).l2FibAddDel(any(L2FibAddDel.class)); - } - - private void whenL2FibAddDelThenFailure() { - doReturn(failedFuture()).when(api).l2FibAddDel(any(L2FibAddDel.class)); - } - - private L2FibAddDel generateL2FibAddDelRequest(final long mac, final byte isAdd) { - final L2FibAddDel request = new L2FibAddDel(); - request.mac = mac; - request.bdId = BD_ID; - request.swIfIndex = IFACE_ID; - request.isAdd = isAdd; - if (isAdd == 1) { - request.staticMac = 1; - request.filterMac = 1; - } - return request; - } - - private L2FibEntry generateL2FibEntry(final PhysAddress address) { - final L2FibEntryBuilder entry = new L2FibEntryBuilder(); - entry.setKey(new L2FibEntryKey(address)); - entry.setPhysAddress(address); - entry.setStaticConfig(true); - entry.setBridgedVirtualInterface(false); - entry.setAction(L2FibFilter.class); - entry.setOutgoingInterface(IFACE_NAME); - return entry.build(); - } - - private void verifyL2FibAddDelWasInvoked(final L2FibAddDel expected) throws - VppInvocationException { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(L2FibAddDel.class); - verify(api).l2FibAddDel(argumentCaptor.capture()); - final L2FibAddDel actual = argumentCaptor.getValue(); - assertEquals(expected.mac, actual.mac); - assertEquals(expected.bdId, actual.bdId); - assertEquals(expected.swIfIndex, actual.swIfIndex); - assertEquals(expected.isAdd, actual.isAdd); - assertEquals(expected.staticMac, actual.staticMac); - assertEquals(expected.filterMac, actual.filterMac); - } - - @Test - public void testCreate() throws Exception { - final long address_vpp = 0x0102030405060000L; - final PhysAddress address = new PhysAddress("01:02:03:04:05:06"); - final L2FibEntry entry = generateL2FibEntry(address); - final InstanceIdentifier id = getL2FibEntryId(address); - - whenL2FibAddDelThenSuccess(); - - customizer.writeCurrentAttributes(id, entry, writeContext); - - verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 1)); - } - - @Test - public void testCreateFailed() throws Exception { - final long address_vpp = 0x1122334455660000L; - final PhysAddress address = new PhysAddress("11:22:33:44:55:66"); - final L2FibEntry entry = generateL2FibEntry(address); - final InstanceIdentifier id = getL2FibEntryId(address); - - whenL2FibAddDelThenFailure(); - - try { - customizer.writeCurrentAttributes(id, entry, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 1)); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test(expected = UnsupportedOperationException.class) - public void testUpdate() throws Exception { - customizer.updateCurrentAttributes(InstanceIdentifier.create(L2FibEntry.class), mock(L2FibEntry.class), - mock(L2FibEntry.class), writeContext); - } - - @Test - public void testDelete() throws Exception { - final long address_vpp = 0x1122334455660000L; - final PhysAddress address = new PhysAddress("11:22:33:44:55:66"); - final L2FibEntry entry = generateL2FibEntry(address); - final InstanceIdentifier id = getL2FibEntryId(address); - - whenL2FibAddDelThenSuccess(); - - customizer.deleteCurrentAttributes(id, entry, writeContext); - - verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 0)); - } - - @Test - public void testDeleteFailed() throws Exception { - final long address_vpp = 0x0102030405060000L; - final PhysAddress address = new PhysAddress("01:02:03:04:05:06"); - final L2FibEntry entry = generateL2FibEntry(address); - final InstanceIdentifier id = getL2FibEntryId(address); - - whenL2FibAddDelThenFailure(); - - try { - customizer.deleteCurrentAttributes(id, entry, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 0)); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionReaderTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionReaderTest.java deleted file mode 100644 index 3b93389e4..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionReaderTest.java +++ /dev/null @@ -1,116 +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.honeycomb.translate.v3po.vppclassifier; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.ModificationCache; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDetails; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.ClassifySessionDump; - -public class ClassifySessionReaderTest extends - ListReaderCustomizerTest { - - private static final String MATCH_1 = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - private static final String MATCH_2 = "00:00:00:00:00:00:01:02:03:04:05:07:00:00:00:00"; - - private static final int TABLE_INDEX = 1; - private static final String TABLE_NAME = "table1"; - - @Mock - private VppClassifierContextManager classifierContext; - - public ClassifySessionReaderTest() { - super(ClassifySession.class, ClassifyTableBuilder.class); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new ClassifySessionReader(api, classifierContext); - } - - private static InstanceIdentifier getClassifySessionId(final String tableName, - final String match) { - return InstanceIdentifier.create(VppClassifierState.class) - .child(ClassifyTable.class, new ClassifyTableKey(tableName)) - .child(ClassifySession.class, new ClassifySessionKey(new HexString(match))); - } - - @Test - public void testReadWithCache() throws ReadFailedException { - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, MATCH_1); - final ClassifySessionBuilder builder = mock(ClassifySessionBuilder.class); - final ModificationCache cache = new ModificationCache(); - final ClassifySessionDetailsReplyDump dump = new ClassifySessionDetailsReplyDump(); - final ClassifySessionDetails details = new ClassifySessionDetails(); - details.match = - new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - dump.classifySessionDetails = Collections.singletonList(details); - cache.put(ClassifySessionReader.CACHE_KEY + id.firstKeyOf(ClassifyTable.class), dump); - when(ctx.getModificationCache()).thenReturn(cache); - - getCustomizer().readCurrentAttributes(id, builder, ctx); - } - - @Test - public void testGetAllIds() throws ReadFailedException { - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, MATCH_1); - final ClassifySessionDetailsReplyDump dump = new ClassifySessionDetailsReplyDump(); - final ClassifySessionDetails details1 = new ClassifySessionDetails(); - details1.match = - new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - final ClassifySessionDetails details2 = new ClassifySessionDetails(); - details2.match = - new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x07, 0x00, 0x00, 0x00, 0x00}; - dump.classifySessionDetails = Arrays.asList(details1, details2); - doReturn(future(dump)).when(api).classifySessionDump(any(ClassifySessionDump.class)); - - when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); - when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - - final List allIds = getCustomizer().getAllIds(id, ctx); - assertEquals(2, allIds.size()); - assertEquals(MATCH_1, allIds.get(0).getMatch().getValue()); - assertEquals(MATCH_2, allIds.get(1).getMatch().getValue()); - } - -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionWriterTest.java deleted file mode 100644 index 5aeab587c..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifySessionWriterTest.java +++ /dev/null @@ -1,179 +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.honeycomb.translate.v3po.vppclassifier; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class ClassifySessionWriterTest extends WriterCustomizerTest { - - private static final int TABLE_INDEX = 123; - private static final String TABLE_NAME = "table123"; - - @Mock - private VppClassifierContextManager classfierContext; - - private ClassifySessionWriter customizer; - private static final int SESSION_INDEX = 456; - - @Override - public void setUp() throws Exception { - customizer = new ClassifySessionWriter(api, classfierContext); - - when(classfierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); - when(classfierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - - final ClassifyTable table = mock(ClassifyTable.class); - when(table.getClassifierNode()).thenReturn(new VppNodeName("ip4-classifier")); - when(writeContext.readAfter(any())).thenReturn(Optional.of(table)); - when(writeContext.readBefore(any())).thenReturn(Optional.of(table)); - } - - private static ClassifySession generateClassifySession(final long opaqueIndex, final String match) { - final ClassifySessionBuilder builder = new ClassifySessionBuilder(); - builder.setOpaqueIndex(new OpaqueIndex(opaqueIndex)); - builder.setHitNext(new VppNode(PacketHandlingAction.Deny)); - builder.setAdvance(123); - builder.setMatch(new HexString(match)); - return builder.build(); - } - - private static InstanceIdentifier getClassifySessionId(final String tableName, - final String match) { - return InstanceIdentifier.create(VppClassifier.class) - .child(ClassifyTable.class, new ClassifyTableKey(tableName)) - .child(ClassifySession.class, new ClassifySessionKey(new HexString(match))); - } - - private void whenClassifyAddDelSessionThenSuccess() { - doReturn(future(new ClassifyAddDelSessionReply())).when(api) - .classifyAddDelSession(any(ClassifyAddDelSession.class)); - } - - private void whenClassifyAddDelSessionThenFailure() { - doReturn(failedFuture()).when(api).classifyAddDelSession(any(ClassifyAddDelSession.class)); - } - - private static ClassifyAddDelSession generateClassifyAddDelSession(final byte isAdd, final int tableIndex, - final int sessionIndex) { - final ClassifyAddDelSession request = new ClassifyAddDelSession(); - request.isAdd = isAdd; - request.tableIndex = tableIndex; - request.opaqueIndex = sessionIndex; - request.hitNextIndex = 0; - request.advance = 123; - request.match = - new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - return request; - } - - @Test - public void testCreate() throws Exception { - final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); - - whenClassifyAddDelSessionThenSuccess(); - - customizer.writeCurrentAttributes(id, classifySession, writeContext); - - verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX)); - } - - @Test - public void testCreateFailed() throws Exception { - final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); - - whenClassifyAddDelSessionThenFailure(); - - try { - customizer.writeCurrentAttributes(id, classifySession, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX)); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test(expected = UnsupportedOperationException.class) - public void testUpdate() throws Exception { - customizer.updateCurrentAttributes(null, null, null, writeContext); - } - - @Test - public void testDelete() throws Exception { - final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); - - whenClassifyAddDelSessionThenSuccess(); - - customizer.deleteCurrentAttributes(id, classifySession, writeContext); - - verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX)); - } - - @Test - public void testDeleteFailed() throws Exception { - final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); - - whenClassifyAddDelSessionThenFailure(); - - try { - customizer.deleteCurrentAttributes(id, classifySession, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX)); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - - customizer.deleteCurrentAttributes(id, classifySession, writeContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableReaderTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableReaderTest.java deleted file mode 100644 index c6085cc92..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableReaderTest.java +++ /dev/null @@ -1,126 +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.honeycomb.translate.v3po.vppclassifier; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; -import java.util.List; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.state.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.ClassifyTableIds; -import io.fd.vpp.jvpp.core.dto.ClassifyTableIdsReply; -import io.fd.vpp.jvpp.core.dto.ClassifyTableInfo; -import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply; - -public class ClassifyTableReaderTest extends - ListReaderCustomizerTest { - - private static final int TABLE_INDEX_1 = 1; - private static final String TABLE_NAME_1 = "table1"; - private static final int TABLE_INDEX_2 = 2; - private static final String TABLE_NAME_2 = "table2"; - - @Mock - private VppClassifierContextManager classifierContext; - - public ClassifyTableReaderTest() { - super(ClassifyTable.class, VppClassifierStateBuilder.class); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new ClassifyTableReader(api, classifierContext); - } - - private static InstanceIdentifier getClassifyTableId(final String name) { - return InstanceIdentifier.create(VppClassifierState.class) - .child(ClassifyTable.class, new ClassifyTableKey(name)); - } - - private static ClassifyTableInfoReply generateClassifyTableInfoReply() { - final ClassifyTableInfoReply reply = new ClassifyTableInfoReply(); - reply.tableId = TABLE_INDEX_1; - reply.nbuckets = 2; - reply.skipNVectors = 0; - reply.matchNVectors = 1; - reply.nextTableIndex = ~0; - reply.missNextIndex = ~0; - reply.mask = - new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - return reply; - } - - private void verifyClasifyTableRead(final ClassifyTableBuilder builder) { - verify(builder).setName(TABLE_NAME_1); - verify(builder).setNbuckets(2L); - verify(builder, times(0)).setNextTable(anyString()); - verify(builder).setMissNext(new VppNode(PacketHandlingAction.Permit)); - verify(builder).setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00")); - verify(builder).setActiveSessions(0L); - } - - @Test - public void testRead() throws ReadFailedException { - doReturn(future(generateClassifyTableInfoReply())).when(api).classifyTableInfo(any(ClassifyTableInfo.class)); - - when(classifierContext.containsTable(TABLE_NAME_1, mappingContext)).thenReturn(true); - when(classifierContext.getTableIndex(TABLE_NAME_1, mappingContext)).thenReturn(TABLE_INDEX_1); - when(classifierContext.getTableBaseNode(TABLE_NAME_1, mappingContext)).thenReturn(Optional.absent()); - - final ClassifyTableBuilder builder = mock(ClassifyTableBuilder.class); - getCustomizer().readCurrentAttributes(getClassifyTableId(TABLE_NAME_1), builder, ctx); - - verifyClasifyTableRead(builder); - } - - @Test - public void testGetAllIds() throws ReadFailedException { - final ClassifyTableIdsReply reply = new ClassifyTableIdsReply(); - reply.ids = new int[] {1, 2}; - doReturn(future(reply)).when(api).classifyTableIds(any(ClassifyTableIds.class)); - - when(classifierContext.getTableName(TABLE_INDEX_1, mappingContext)).thenReturn(TABLE_NAME_1); - when(classifierContext.getTableName(TABLE_INDEX_2, mappingContext)).thenReturn(TABLE_NAME_2); - - final List allIds = getCustomizer().getAllIds(getClassifyTableId(TABLE_NAME_1), ctx); - - assertEquals(reply.ids.length, allIds.size()); - assertEquals(TABLE_NAME_1, allIds.get(0).getName()); - assertEquals(TABLE_NAME_2, allIds.get(1).getName()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableWriterTest.java deleted file mode 100644 index 0869986ee..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/ClassifyTableWriterTest.java +++ /dev/null @@ -1,181 +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.honeycomb.translate.v3po.vppclassifier; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; -import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class ClassifyTableWriterTest extends WriterCustomizerTest { - - private static final int TABLE_INDEX = 123; - private static final String TABLE_NAME = "table123"; - - @Mock - private VppClassifierContextManager classifierContext; - - private ClassifyTableWriter customizer; - - @Override - public void setUp() throws Exception { - customizer = new ClassifyTableWriter(api, classifierContext); - } - - private static ClassifyTable generateClassifyTable(final String name) { - final ClassifyTableBuilder builder = new ClassifyTableBuilder(); - builder.setName(name); - builder.setClassifierNode(new VppNodeName("ip4-classifier")); - builder.setKey(new ClassifyTableKey(name)); - builder.setSkipNVectors(0L); - builder.setNbuckets(2L); - builder.setMemorySize(2L << 20); - builder.setMissNext(new VppNode(PacketHandlingAction.Permit)); - builder.setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00")); - return builder.build(); - } - - private static InstanceIdentifier getClassifyTableId(final String name) { - return InstanceIdentifier.create(VppClassifier.class) - .child(ClassifyTable.class, new ClassifyTableKey(name)); - } - - private void whenClassifyAddDelTableThenSuccess() { - final ClassifyAddDelTableReply reply = new ClassifyAddDelTableReply(); - reply.newTableIndex = TABLE_INDEX; - doReturn(future(reply)).when(api).classifyAddDelTable(any(ClassifyAddDelTable.class)); - } - - private void whenClassifyAddDelTableThenFailure() { - doReturn(failedFuture()).when(api).classifyAddDelTable(any(ClassifyAddDelTable.class)); - } - - private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd) { - return generateClassifyAddDelTable(isAdd, -1); - } - - private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd, final int tableIndex) { - final ClassifyAddDelTable request = new ClassifyAddDelTable(); - request.isAdd = isAdd; - request.tableIndex = tableIndex; - request.nbuckets = 2; - request.memorySize = 2 << 20; - request.skipNVectors = 0; - request.matchNVectors = 1; - request.nextTableIndex = ~0; - request.missNextIndex = ~0; - request.mask = - new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; - return request; - } - - @Test - public void testCreate() throws Exception { - final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - - whenClassifyAddDelTableThenSuccess(); - - customizer.writeCurrentAttributes(id, classifyTable, writeContext); - - verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 1)); - verify(classifierContext) - .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext); - } - - @Test - public void testCreateFailed() throws Exception { - final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - - whenClassifyAddDelTableThenFailure(); - - try { - customizer.writeCurrentAttributes(id, classifyTable, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 1)); - verify(classifierContext, times(0)) - .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext); - return; - } - fail("WriteFailedException.CreateFailedException was expected"); - } - - @Test - public void testDelete() throws Exception { - final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - - when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); - when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - whenClassifyAddDelTableThenSuccess(); - - customizer.deleteCurrentAttributes(id, classifyTable, writeContext); - - verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 0, TABLE_INDEX)); - } - - @Test - public void testDeleteFailed() throws Exception { - final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - - when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true); - when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX); - whenClassifyAddDelTableThenFailure(); - - try { - customizer.deleteCurrentAttributes(id, classifyTable, writeContext); - } catch (WriteFailedException e) { - assertTrue(e.getCause() instanceof VppBaseCallException); - verify(api).classifyAddDelTable(generateClassifyAddDelTable((byte) 0, TABLE_INDEX)); - return; - } - fail("WriteFailedException.DeleteFailedException was expected"); - - customizer.deleteCurrentAttributes(id, classifyTable, writeContext); - } - - @Test(expected = UnsupportedOperationException.class) - public void testUpdate() throws Exception { - final ClassifyTable classifyTableBefore = generateClassifyTable(TABLE_NAME); - final InstanceIdentifier id = getClassifyTableId(TABLE_NAME); - customizer.updateCurrentAttributes(id, classifyTableBefore, new ClassifyTableBuilder().build(), writeContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManagerImplTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManagerImplTest.java deleted file mode 100644 index 667d06b6c..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppclassifier/VppClassifierContextManagerImplTest.java +++ /dev/null @@ -1,163 +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.honeycomb.translate.v3po.vppclassifier; - -import static io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManagerImpl.VPP_CLASSIFIER_CONTEXT_IID; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import java.util.Arrays; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.VppClassifierContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.ClassifyTableContextKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev160909.vpp.classifier.context.classify.table.context.NodeContextKey; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; - -public class VppClassifierContextManagerImplTest { - - private static final int TABLE_ID_0 = 0; - private static final String TABLE_NAME_0 = "table0"; - private static final KeyedInstanceIdentifier TABLE_IID_0 = - VPP_CLASSIFIER_CONTEXT_IID.child(ClassifyTableContext.class, new ClassifyTableContextKey(TABLE_NAME_0)); - - private static final int TABLE_ID_1 = 1; - private static final String TABLE_NAME_1 = "table1"; - - private VppClassifierContextManagerImpl vppClassfierContext; - - @Mock - private MappingContext ctx; - - @Before - public void setUp() throws Exception { - initMocks(this); - vppClassfierContext = new VppClassifierContextManagerImpl("classify-table-"); - } - - @Test - public void testAddTable() throws Exception { - final String classfierNodeName = "node123"; - vppClassfierContext.addTable(TABLE_ID_0, TABLE_NAME_0, new VppNodeName(classfierNodeName), ctx); - verify(ctx).put(TABLE_IID_0, table(TABLE_ID_0, TABLE_NAME_0, classfierNodeName)); - } - - @Test - public void testContainsTable() throws Exception { - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.absent()); - assertFalse(vppClassfierContext.containsTable(TABLE_NAME_0, ctx)); - } - - @Test - public void testGetTableIndex() throws Exception { - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(table(TABLE_ID_0, TABLE_NAME_0))); - assertEquals(TABLE_ID_0, vppClassfierContext.getTableIndex(TABLE_NAME_0, ctx)); - } - - @Test - public void testGetTableName() throws Exception { - when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)) - .thenReturn(Optional.of(context(table(TABLE_ID_0, TABLE_NAME_0), table(TABLE_ID_1, TABLE_NAME_1)))); - assertEquals(TABLE_NAME_0, (vppClassfierContext.getTableName(TABLE_ID_0, ctx))); - } - - @Test - public void testGetTableBaseNode() throws Exception { - final String classfierNodeName = "node123"; - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(table(TABLE_ID_0, TABLE_NAME_0, classfierNodeName))); - vppClassfierContext.getTableBaseNode(TABLE_NAME_0, ctx); - assertEquals(Optional.of(classfierNodeName), (vppClassfierContext.getTableBaseNode(TABLE_NAME_0, ctx))); - } - - @Test - public void testRemoveTable() throws Exception { - vppClassfierContext.removeTable(TABLE_NAME_0, ctx); - verify(ctx).delete(TABLE_IID_0); - } - - @Test - public void testAddNodeName() throws Exception { - final String nodeName = "node123"; - final int nodeIndex = 1; - - vppClassfierContext.addNodeName(TABLE_NAME_0, nodeIndex, nodeName, ctx); - verify(ctx).put( - TABLE_IID_0.child(NodeContext.class, new NodeContextKey(nodeName)), - node(nodeName, nodeIndex) - ); - } - - @Test - public void testGetNonExistingNodeName() throws Exception { - when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(table(TABLE_ID_1, TABLE_NAME_1)))); - assertFalse(vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx).isPresent()); - } - - @Test - public void testGetNodeNameMissingNodeCtx() throws Exception { - final ClassifyTableContext tableCtx = table(TABLE_ID_0, TABLE_NAME_0, "aa"); - when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(tableCtx))); - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(tableCtx)); - assertEquals(Optional.absent(), vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx)); - } - - @Test - public void testGetNodeName() throws Exception { - final ClassifyTableContext tableCtx = table(TABLE_ID_0, TABLE_NAME_0, "aa", node("node123", 123)); - when(ctx.read(VPP_CLASSIFIER_CONTEXT_IID)).thenReturn(Optional.of(context(tableCtx))); - when(ctx.read(TABLE_IID_0)).thenReturn(Optional.of(tableCtx)); - assertEquals(Optional.of("node123"), vppClassfierContext.getNodeName(TABLE_ID_0, 123, ctx)); - } - - private VppClassifierContext context(ClassifyTableContext... tables) { - VppClassifierContextBuilder context = new VppClassifierContextBuilder(); - context.setClassifyTableContext(Arrays.asList(tables)); - return context.build(); - } - - private static ClassifyTableContext table(final Integer id, final String name) { - return table(id, name, null); - } - - private static ClassifyTableContext table(final Integer id, final String name, final String classfierNodeName, - final NodeContext... nodeContexts) { - final ClassifyTableContextBuilder builder = - new ClassifyTableContextBuilder().setIndex(id).setName(name).setClassifierNodeName(classfierNodeName); - - if (nodeContexts.length > 0) { - builder.setNodeContext(Arrays.asList(nodeContexts)); - } - - return builder.build(); - } - - private NodeContext node(final String nodeName, final int nodeIndex) { - return new NodeContextBuilder().setName(nodeName).setIndex(nodeIndex).build(); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/BridgeDomainCustomizerTest.java deleted file mode 100644 index 2f31adddd..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/BridgeDomainCustomizerTest.java +++ /dev/null @@ -1,47 +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.honeycomb.translate.v3po.vppstate; - -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; - -public class BridgeDomainCustomizerTest - extends ListReaderCustomizerTest { - - private NamingContext bdContext; - private NamingContext interfacesContext; - - public BridgeDomainCustomizerTest() { - super(BridgeDomain.class, BridgeDomainsBuilder.class); - } - - @Override - public void setUp() { - bdContext = new NamingContext("generatedBdName", "bd-test-instance"); - interfacesContext = new NamingContext("generatedIfaceName", "ifc-test-instance"); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new BridgeDomainCustomizer(api, bdContext); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/L2FibEntryCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/L2FibEntryCustomizerTest.java deleted file mode 100644 index a76baea60..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/L2FibEntryCustomizerTest.java +++ /dev/null @@ -1,124 +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.honeycomb.translate.v3po.vppstate; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.ExecutionException; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibForward; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.core.dto.L2FibTableDump; -import io.fd.vpp.jvpp.core.dto.L2FibTableEntry; -import io.fd.vpp.jvpp.core.dto.L2FibTableEntryReplyDump; - -public class L2FibEntryCustomizerTest extends ListReaderCustomizerTest { - - private static final String BD_NAME = "testBD0"; - private static final int BD_ID = 111; - private static final String IFACE_NAME = "eth0"; - private static final int IFACE_ID = 123; - private static final String BD_CTX_NAME = "bd-test-instance"; - private static final String IFC_CTX_NAME = "ifc-test-instance"; - private NamingContext bdContext; - private NamingContext interfacesContext; - - public L2FibEntryCustomizerTest() { - super(L2FibEntry.class, L2FibTableBuilder.class); - } - - @Override - public void setUp() { - bdContext = new NamingContext("generatedBdName", BD_CTX_NAME); - defineMapping(mappingContext, BD_NAME, BD_ID, BD_CTX_NAME); - interfacesContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new L2FibEntryCustomizer(api, bdContext, interfacesContext); - } - - private static InstanceIdentifier getL2FibEntryId(final String bdName, final PhysAddress address) { - return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(bdName)) - .child(L2FibTable.class).child(L2FibEntry.class, new L2FibEntryKey(address)); - } - - private void whenL2FibTableDumpThenReturn(final List l2FibTableEntryList) - throws ExecutionException, InterruptedException, VppInvocationException { - final L2FibTableEntryReplyDump reply = new L2FibTableEntryReplyDump(); - reply.l2FibTableEntry = l2FibTableEntryList; - when(api.l2FibTableDump(any(L2FibTableDump.class))).thenReturn(future(reply)); - } - - @Test - public void testRead() throws Exception { - final long address_vpp = 0x0000010203040506L; - final PhysAddress address = new PhysAddress("01:02:03:04:05:06"); - defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); - - whenL2FibTableDumpThenReturn(Collections.singletonList(generateL2FibEntry(address_vpp))); - - final L2FibEntryBuilder builder = mock(L2FibEntryBuilder.class); - getCustomizer().readCurrentAttributes(getL2FibEntryId(BD_NAME, address), builder, ctx); - - verify(builder).setAction(L2FibForward.class); - verify(builder).setBridgedVirtualInterface(false); - verify(builder).setOutgoingInterface(IFACE_NAME); - verify(builder).setStaticConfig(false); - verify(builder).setPhysAddress(address); - verify(builder).setKey(new L2FibEntryKey(address)); - } - - private L2FibTableEntry generateL2FibEntry(final long mac) { - final L2FibTableEntry entry = new L2FibTableEntry(); - entry.mac = mac; - entry.swIfIndex = IFACE_ID; - return entry; - } - - @Test - public void testGetAllIds() throws Exception { - final long address_vpp = 0x0000112233445566L; - final PhysAddress address = new PhysAddress("11:22:33:44:55:66"); - - whenL2FibTableDumpThenReturn(Collections.singletonList(generateL2FibEntry(address_vpp))); - - final List ids = getCustomizer().getAllIds(getL2FibEntryId(BD_NAME, address), ctx); - assertEquals(1, ids.size()); - assertEquals(address, ids.get(0).getPhysAddress()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/VersionCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/VersionCustomizerTest.java deleted file mode 100644 index ab35bb330..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/VersionCustomizerTest.java +++ /dev/null @@ -1,60 +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.honeycomb.translate.v3po.vppstate; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; -import io.fd.vpp.jvpp.core.dto.ShowVersion; -import io.fd.vpp.jvpp.core.dto.ShowVersionReply; -import io.fd.vpp.jvpp.dto.ControlPing; -import io.fd.vpp.jvpp.dto.ControlPingReply; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.VersionBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class VersionCustomizerTest extends ReaderCustomizerTest { - - public VersionCustomizerTest() { - super(Version.class, VppStateBuilder.class); - } - - @Override - protected ReaderCustomizer initCustomizer() { - return new VersionCustomizer(api); - } - - @Test - public void testReadCurrentAttributes() throws Exception { - final ShowVersionReply reply = new ShowVersionReply(); - reply.version = new byte[] {}; - reply.program = new byte[] {}; - reply.buildDate = new byte[] {}; - reply.buildDirectory = new byte[] {}; - - when(api.showVersion(any(ShowVersion.class))).thenReturn(future(reply)); - when(api.send(any(ControlPing.class))).thenReturn(future(new ControlPingReply())); - getCustomizer().readCurrentAttributes(InstanceIdentifier.create(Version.class), new VersionBuilder(), ctx); - verify(api).showVersion(any(ShowVersion.class)); - verify(api).send(any(ControlPing.class)); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/VppStateTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/VppStateTest.java deleted file mode 100644 index cdc352ac5..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/vppstate/VppStateTest.java +++ /dev/null @@ -1,326 +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.honeycomb.translate.v3po.vppstate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.common.base.Optional; -import com.google.common.collect.Iterables; -import com.google.common.collect.Multimap; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.ModificationCache; -import io.fd.honeycomb.translate.impl.read.GenericListReader; -import io.fd.honeycomb.translate.impl.read.GenericReader; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.read.registry.ReaderRegistry; -import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; -import io.fd.honeycomb.vpp.test.util.NamingContextHelper; -import io.fd.honeycomb.translate.vpp.util.NamingContext; -import io.fd.honeycomb.vpp.test.util.FutureProducer; -import io.fd.vpp.jvpp.dto.ControlPing; -import io.fd.vpp.jvpp.dto.ControlPingReply; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.VersionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; -import io.fd.vpp.jvpp.core.dto.L2FibTableDump; -import io.fd.vpp.jvpp.core.dto.L2FibTableEntry; -import io.fd.vpp.jvpp.core.dto.L2FibTableEntryReplyDump; -import io.fd.vpp.jvpp.core.dto.ShowVersion; -import io.fd.vpp.jvpp.core.dto.ShowVersionReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -public class VppStateTest implements FutureProducer, NamingContextHelper { - - private static final String BD_CTX_NAME = "bd-test-instance"; - @Mock - private FutureJVppCore api; - @Mock - private ReadContext ctx; - @Mock - private MappingContext mappingContext; - - private NamingContext bdContext; - - private ReaderRegistry readerRegistry; - - private static InstanceIdentifier bridgeDomainsId; - - /** - * Create root VppState reader with all its children wired. - */ - private static ReaderRegistry getVppStateReader(@Nonnull final FutureJVppCore jVpp, - @Nonnull final NamingContext bdContext) { - final CompositeReaderRegistryBuilder registry = new CompositeReaderRegistryBuilder(); - - // VppState(Structural) - final InstanceIdentifier vppStateId = InstanceIdentifier.create(VppState.class); - registry.addStructuralReader(vppStateId, VppStateBuilder.class); - // Version - registry.add(new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp))); - // BridgeDomains(Structural) - bridgeDomainsId = vppStateId.child(BridgeDomains.class); - registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class); - // BridgeDomain - registry.add(getBridgeDomainReader(jVpp, bdContext)); - return registry.build(); - } - - private static GenericListReader getBridgeDomainReader( - final @Nonnull FutureJVppCore jVpp, final @Nonnull NamingContext bdContext) { - final InstanceIdentifier bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class); - return new GenericListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdContext)); - } - - @Before - public void setUp() throws Exception { - initMocks(this); - final ModificationCache cache = new ModificationCache(); - doReturn(cache).when(ctx).getModificationCache(); - doReturn(mappingContext).when(ctx).getMappingContext(); - - bdContext = new NamingContext("generatedBdName", BD_CTX_NAME); - readerRegistry = getVppStateReader(api, bdContext); - } - - private static Version getVersion() { - return new VersionBuilder() - .setName("test") - .setBuildDirectory("1") - .setBranch("2") - .setBuildDate("3") - .setPid(0L) - .build(); - } - - private void whenShowVersionThenReturn(final Version version) { - final ShowVersionReply reply = new ShowVersionReply(); - reply.buildDate = version.getBuildDate().getBytes(); - reply.program = version.getName().getBytes(); - reply.version = version.getBranch().getBytes(); - reply.buildDirectory = version.getBuildDirectory().getBytes(); - when(api.showVersion(any(ShowVersion.class))).thenReturn(future(reply)); - // Version Customizer uses ControlPing to obtain PID - when(api.send(any(ControlPing.class))).thenReturn(future(new ControlPingReply())); - } - - private void whenL2FibTableDumpThenReturn(final List entryList) { - final L2FibTableEntryReplyDump reply = new L2FibTableEntryReplyDump(); - reply.l2FibTableEntry = entryList; - when(api.l2FibTableDump(any(L2FibTableDump.class))).thenReturn(future(reply)); - } - - private void whenBridgeDomainDumpThenReturn(final List bdList) { - final BridgeDomainDetailsReplyDump reply = new BridgeDomainDetailsReplyDump(); - reply.bridgeDomainDetails = bdList; - - doAnswer(invocation -> { - BridgeDomainDump request = (BridgeDomainDump) invocation.getArguments()[0]; - if (request.bdId == -1) { - reply.bridgeDomainDetails = bdList; - } else { - reply.bridgeDomainDetails = Collections.singletonList(bdList.get(request.bdId)); - } - return future(reply); - }).when(api).bridgeDomainDump(any(BridgeDomainDump.class)); - } - - @Test - public void testReadAll() throws Exception { - final Version version = getVersion(); - whenShowVersionThenReturn(version); - - final BridgeDomainDetails bridgeDomainDetails = new BridgeDomainDetails(); - final BridgeDomainDetails bridgeDomainDetails2 = new BridgeDomainDetails(); - bridgeDomainDetails2.bdId = 1; - - final List bdList = Arrays.asList(bridgeDomainDetails, bridgeDomainDetails2); - mockBdMapping(bridgeDomainDetails, "bd1"); - mockBdMapping(bridgeDomainDetails2, "bd2"); - - whenBridgeDomainDumpThenReturn(bdList); - - final Multimap, ? extends DataObject> dataObjects = - readerRegistry.readAll(ctx); - assertEquals(dataObjects.size(), 1); - final VppState dataObject = - (VppState) Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet()))); - assertEquals(version, dataObject.getVersion()); - assertEquals(2, dataObject.getBridgeDomains().getBridgeDomain().size()); - } - - @Test - public void testReadSpecific() throws Exception { - final Version version = getVersion(); - whenShowVersionThenReturn(version); - whenBridgeDomainDumpThenReturn(Collections.emptyList()); - - final Optional read = readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx); - assertTrue(read.isPresent()); - assertEquals(version, ((VppState) read.get()).getVersion()); - } - - @Test - public void testReadBridgeDomains() throws Exception { - final Version version = getVersion(); - whenShowVersionThenReturn(version); - final BridgeDomainDetails details = new BridgeDomainDetails(); - whenBridgeDomainDumpThenReturn(Collections.singletonList(details)); - - mockBdMapping(details, "bdn1"); - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); - - Optional read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class), ctx); - assertTrue(read.isPresent()); - assertEquals(readRoot.getBridgeDomains(), read.get()); - } - - /** - * L2fib does not have a dedicated reader, relying on auto filtering - */ - @Test - @Ignore("L2 FIB was moved to dedicated customizer. TODO: add infra test that covers such case") - @SuppressWarnings("unchecked") - public void testReadL2Fib() throws Exception { - final BridgeDomainDetails bd = new BridgeDomainDetails(); - bd.bdId = 0; - final String bdName = "bdn1"; - mockBdMapping(bd, bdName); - defineMapping(mappingContext, "eth1", 0, "ifc-test-instance"); - - whenBridgeDomainDumpThenReturn(Collections.singletonList(bd)); - final L2FibTableEntry l2FibEntry = new L2FibTableEntry(); - l2FibEntry.bdId = 0; - l2FibEntry.mac = 0x0605040302010000L; - whenL2FibTableDumpThenReturn(Collections.singletonList(l2FibEntry)); - - // Deep child without a dedicated reader with specific l2fib key - final InstanceIdentifier idExisting = - InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("bdn1")).child(L2FibTable.class) - .child(L2FibEntry.class, new L2FibEntryKey(new PhysAddress("01:02:03:04:05:06"))); - Optional read = - readerRegistry.read(idExisting, ctx); - assertTrue(read.isPresent()); - - // non existing l2fib - final InstanceIdentifier idNonExisting = - InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("bdn1")).child(L2FibTable.class) - .child(L2FibEntry.class, new L2FibEntryKey(new PhysAddress("FF:FF:FF:04:05:06"))); - read = readerRegistry.read(idNonExisting, ctx); - assertFalse(read.isPresent()); - } - - private void mockBdMapping(final BridgeDomainDetails bd, final String bdName) { - defineMapping(mappingContext, bdName, bd.bdId, BD_CTX_NAME); - } - - @Test - public void testReadBridgeDomainAll() throws Exception { - final Version version = getVersion(); - whenShowVersionThenReturn(version); - final BridgeDomainDetails details = new BridgeDomainDetails(); - whenBridgeDomainDumpThenReturn(Collections.singletonList(details)); - mockBdMapping(details, "bd2"); - - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); - - final GenericListReader bridgeDomainReader = - getBridgeDomainReader(api, bdContext); - - final List read = - bridgeDomainReader.readList(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class), ctx); - - assertEquals(readRoot.getBridgeDomains().getBridgeDomain(), read); - } - - @Test - public void testReadBridgeDomain() throws Exception { - final BridgeDomainDetails bd = new BridgeDomainDetails(); - bd.bdId = 0; - final String bdName = "bdn1"; - mockBdMapping(bd, bdName); - - whenBridgeDomainDumpThenReturn(Collections.singletonList(bd)); - whenShowVersionThenReturn(getVersion()); - - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); - - final Optional read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey(bdName)), ctx); - - assertTrue(read.isPresent()); - assertEquals(readRoot.getBridgeDomains().getBridgeDomain().stream().filter( - input -> input.getKey().getName().equals(bdName)).findFirst().get(), - read.get()); - } - - @Test(expected = ReadFailedException.class) - public void testReadBridgeDomainNotExisting() throws Exception { - final String nonExistingBdName = "NOT EXISTING"; - noMappingDefined(mappingContext, nonExistingBdName, BD_CTX_NAME); - - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey(nonExistingBdName)), ctx); - } - - @Test - public void testReadVersion() throws Exception { - whenShowVersionThenReturn(getVersion()); - whenBridgeDomainDumpThenReturn(Collections.emptyList()); - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); - - Optional read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(Version.class), ctx); - assertTrue(read.isPresent()); - assertEquals(readRoot.getVersion(), read.get()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/vpp/util/SubinterfaceUtilsTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/vpp/util/SubinterfaceUtilsTest.java deleted file mode 100644 index da2a0427d..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/vpp/util/SubinterfaceUtilsTest.java +++ /dev/null @@ -1,32 +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.honeycomb.translate.vpp.util; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class SubinterfaceUtilsTest { - - @Test - public void testGetSubInterfaceName() throws Exception { - final String superIfName = "GigabitEthernet0/9/0"; - final int subIfaceId = 123; - final String expectedSubIfaceName = "GigabitEthernet0/9/0.123"; - assertEquals(expectedSubIfaceName, SubInterfaceUtils.getSubInterfaceName(superIfName, subIfaceId)); - } -} \ No newline at end of file -- cgit 1.2.3-korg