From a7147d16c31d9028c6b5dc557264433de0f11c91 Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Fri, 23 Sep 2016 16:39:09 +0200 Subject: HONEYCOMB-145 - Utility Class Refactoring problematic mockito-all changed to mockito-core( https://github.com/mockito/mockito/issues/324) Translate Utils Splitted to multiple Trait Interfaces Ipv4Translator - Logic for translation of ipv4-based data Ipv6Translator - Logic for translation of ipv6-based data MacTranslator - Logic for translation of mac-based data AddressTranslator - Aggregation trait for Ipv4/Ipv6/Mac JvppReplyConsumer - Logic for extracting replies from jvpp calls ByteDataTranslator - any byte-based conversions Plus some existing utility classes changed to traits Change-Id: I342b625954223966802e65dca0fabf8456c89345 Signed-off-by: Jan Srnicek --- v3po/v3po2vpp/pom.xml | 2 +- .../v3po/initializers/InterfacesInitializer.java | 4 +- .../translate/v3po/interfaces/AclWriter.java | 15 +- .../translate/v3po/interfaces/GreCustomizer.java | 58 +++-- .../v3po/interfaces/InterconnectionWriteUtils.java | 38 +-- .../v3po/interfaces/InterfaceCustomizer.java | 33 ++- .../v3po/interfaces/ProxyArpCustomizer.java | 11 +- .../v3po/interfaces/RewriteCustomizer.java | 12 +- .../v3po/interfaces/RoutingCustomizer.java | 19 +- .../v3po/interfaces/SubInterfaceCustomizer.java | 40 +-- .../v3po/interfaces/SubInterfaceL2Customizer.java | 2 +- .../translate/v3po/interfaces/TapCustomizer.java | 48 ++-- .../v3po/interfaces/VhostUserCustomizer.java | 32 ++- .../translate/v3po/interfaces/VxlanCustomizer.java | 32 ++- .../v3po/interfaces/VxlanGpeCustomizer.java | 62 +++-- .../v3po/interfaces/acl/AbstractAceWriter.java | 22 +- .../v3po/interfaces/acl/AceEthWriter.java | 25 +- .../v3po/interfaces/acl/AceIp4Writer.java | 28 +- .../v3po/interfaces/acl/IetfAClWriter.java | 39 ++- .../v3po/interfaces/ip/Ipv4AddressCustomizer.java | 9 +- .../interfaces/ip/Ipv4NeighbourCustomizer.java | 17 +- .../v3po/interfaces/ip/Ipv4WriteUtils.java | 111 -------- .../translate/v3po/interfaces/ip/Ipv4Writer.java | 109 ++++++++ .../v3po/interfaces/ip/Ipv6Customizer.java | 2 +- .../ip/SubInterfaceIpv4AddressCustomizer.java | 34 +-- .../ip/subnet/validation/SubnetValidator.java | 8 +- .../v3po/interfacesstate/AclCustomizer.java | 10 +- .../v3po/interfacesstate/EthernetCustomizer.java | 10 +- .../v3po/interfacesstate/GreCustomizer.java | 25 +- .../interfacesstate/InterconnectionReadUtils.java | 17 +- .../v3po/interfacesstate/InterfaceCustomizer.java | 64 ++--- .../interfacesstate/InterfaceDataTranslator.java | 287 ++++++++++++++++++++ .../v3po/interfacesstate/InterfaceUtils.java | 289 --------------------- .../v3po/interfacesstate/L2Customizer.java | 5 +- .../v3po/interfacesstate/RewriteCustomizer.java | 6 +- .../interfacesstate/SubInterfaceAclCustomizer.java | 12 +- .../interfacesstate/SubInterfaceCustomizer.java | 71 ++--- .../interfacesstate/SubInterfaceL2Customizer.java | 2 +- .../v3po/interfacesstate/TapCustomizer.java | 22 +- .../v3po/interfacesstate/VhostUserCustomizer.java | 42 +-- .../v3po/interfacesstate/VxlanCustomizer.java | 26 +- .../v3po/interfacesstate/VxlanGpeCustomizer.java | 29 ++- .../interfacesstate/ip/Ipv4AddressCustomizer.java | 67 +++-- .../ip/Ipv4NeighbourCustomizer.java | 2 +- .../v3po/interfacesstate/ip/Ipv4ReadUtils.java | 130 --------- .../v3po/interfacesstate/ip/Ipv4Reader.java | 68 +++++ .../ip/SubInterfaceIpv4AddressCustomizer.java | 50 ++-- .../ip/dump/AddressDumpExecutor.java | 47 ++++ .../ip/dump/check/AddressDumpCheck.java | 16 ++ .../ip/dump/params/AddressDumpParams.java | 28 ++ .../InterfaceChangeNotificationProducer.java | 37 +-- .../vpp/ArpTerminationTableEntryCustomizer.java | 25 +- .../translate/v3po/vpp/BridgeDomainCustomizer.java | 27 +- .../translate/v3po/vpp/L2FibEntryCustomizer.java | 26 +- .../v3po/vppclassifier/ClassifySessionReader.java | 38 +-- .../v3po/vppclassifier/ClassifySessionWriter.java | 38 +-- .../v3po/vppclassifier/ClassifyTableReader.java | 24 +- .../v3po/vppclassifier/ClassifyTableWriter.java | 26 +- .../v3po/vppclassifier/VppNodeWriter.java | 20 +- .../v3po/vppstate/BridgeDomainCustomizer.java | 12 +- .../v3po/vppstate/L2FibEntryCustomizer.java | 29 +-- .../translate/v3po/vppstate/VersionCustomizer.java | 17 +- .../v3po/DisabledInterfacesManagerTest.java | 3 + .../v3po/interfaces/InterfaceTypeTestUtils.java | 2 +- .../v3po/interfaces/VhostUserCustomizerTest.java | 20 +- .../interfaces/ip/Ipv4NeighbourCustomizerTest.java | 8 +- .../interfacesstate/InterfaceCustomizerTest.java | 24 +- .../InterfaceDataTranslatorTest.java | 55 ++++ .../v3po/interfacesstate/InterfaceUtilsTest.java | 55 ---- .../ip/Ipv4AddressCustomizerTest.java | 121 +++------ .../v3po/vpp/BridgeDomainCustomizerTest.java | 46 ++-- .../v3po/vpp/L2FibEntryCustomizerTest.java | 12 +- 72 files changed, 1445 insertions(+), 1357 deletions(-) delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4WriteUtils.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Writer.java create 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/InterfaceUtils.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4ReadUtils.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Reader.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/AddressDumpExecutor.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/check/AddressDumpCheck.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java create 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/InterfaceUtilsTest.java (limited to 'v3po') diff --git a/v3po/v3po2vpp/pom.xml b/v3po/v3po2vpp/pom.xml index ba5cf0352..07210160c 100644 --- a/v3po/v3po2vpp/pom.xml +++ b/v3po/v3po2vpp/pom.xml @@ -98,7 +98,7 @@ org.mockito - mockito-all + mockito-core test diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/initializers/InterfacesInitializer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/initializers/InterfacesInitializer.java index d78f33296..7ecf0c0f5 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/initializers/InterfacesInitializer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/initializers/InterfacesInitializer.java @@ -49,20 +49,20 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.AclBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.EthernetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.GreBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.TapBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUserBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpeBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.GreBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Acl; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Ethernet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Gre; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.L2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Tap; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VhostUser; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Vxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VxlanGpe; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Gre; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/AclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/AclWriter.java index a1bdf6aa9..ce4494757 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/AclWriter.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/AclWriter.java @@ -17,10 +17,10 @@ package io.fd.honeycomb.translate.v3po.interfaces; import static com.google.common.base.Preconditions.checkNotNull; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte; import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; import java.util.concurrent.CompletionStage; @@ -36,13 +36,14 @@ import org.openvpp.jvpp.core.dto.InputAclSetInterface; import org.openvpp.jvpp.core.dto.InputAclSetInterfaceReply; import org.openvpp.jvpp.core.future.FutureJVppCore; -interface AclWriter { +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, + @Nonnegative final int ifIndex, + @Nonnull final VppClassifierContextManager classifyTableContext, @Nonnull final MappingContext mappingContext) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { final InputAclSetInterface request = new InputAclSetInterface(); request.isAdd = booleanToByte(isAdd); request.swIfIndex = ifIndex; @@ -67,8 +68,8 @@ interface AclWriter { } final CompletionStage inputAclSetInterfaceReplyCompletionStage = - futureJVppCore.inputAclSetInterface(request); + futureJVppCore.inputAclSetInterface(request); - TranslateUtils.getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), 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 index 1e3057d8c..04398f4b3 100644 --- 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 @@ -20,8 +20,8 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.common.net.InetAddresses; import io.fd.honeycomb.translate.v3po.util.AbstractInterfaceTypeCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; @@ -35,13 +35,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Gre; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.openvpp.jvpp.VppBaseCallException; -import org.openvpp.jvpp.core.future.FutureJVppCore; import org.openvpp.jvpp.core.dto.GreAddDelTunnel; import org.openvpp.jvpp.core.dto.GreAddDelTunnelReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class GreCustomizer extends AbstractInterfaceTypeCustomizer { +public class GreCustomizer extends AbstractInterfaceTypeCustomizer implements JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(GreCustomizer.class); private final NamingContext interfaceContext; @@ -51,6 +51,17 @@ public class GreCustomizer extends AbstractInterfaceTypeCustomizer { 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; @@ -58,7 +69,7 @@ public class GreCustomizer extends AbstractInterfaceTypeCustomizer { @Override protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Gre dataAfter, - @Nonnull final WriteContext writeContext) + @Nonnull final WriteContext writeContext) throws WriteFailedException { final String swIfName = id.firstKeyOf(Interface.class).getName(); try { @@ -91,8 +102,10 @@ public class GreCustomizer extends AbstractInterfaceTypeCustomizer { } private void createGreTunnel(final InstanceIdentifier id, final String swIfName, final Gre gre, - final WriteContext writeContext) throws VppBaseCallException, WriteTimeoutException { - final byte isIpv6 = (byte) (isIpv6(gre) ? 1 : 0); + final WriteContext writeContext) throws VppBaseCallException, WriteTimeoutException { + final byte isIpv6 = (byte) (isIpv6(gre) + ? 1 + : 0); final InetAddress srcAddress = InetAddresses.forString(getAddressString(gre.getSrc())); final InetAddress dstAddress = InetAddresses.forString(getAddressString(gre.getDst())); @@ -104,9 +117,9 @@ public class GreCustomizer extends AbstractInterfaceTypeCustomizer { dstAddress.getAddress(), outerFibId, isIpv6)); final GreAddDelTunnelReply reply = - TranslateUtils.getReplyForWrite(greAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(greAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Gre tunnel set successfully for: {}, gre: {}", swIfName, gre); - if(interfaceContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { + 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 @@ -116,7 +129,7 @@ public class GreCustomizer extends AbstractInterfaceTypeCustomizer { // 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); + reply.swIfIndex, formerName, swIfName); interfaceContext.removeName(formerName, writeContext.getMappingContext()); } // Add new interface to our interface context @@ -126,22 +139,26 @@ public class GreCustomizer extends AbstractInterfaceTypeCustomizer { 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()); + gre.getDst()); return true; } else { checkArgument(gre.getDst().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", gre.getSrc(), - gre.getDst()); + gre.getDst()); return false; } } private String getAddressString(final IpAddress addr) { - return addr.getIpv4Address() == null ? addr.getIpv6Address().getValue() : addr.getIpv4Address().getValue(); + 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 VppBaseCallException, WriteTimeoutException { - final byte isIpv6 = (byte) (isIpv6(gre) ? 1 : 0); + final WriteContext writeContext) throws VppBaseCallException, WriteTimeoutException { + final byte isIpv6 = (byte) (isIpv6(gre) + ? 1 + : 0); final InetAddress srcAddress = InetAddresses.forString(getAddressString(gre.getSrc())); final InetAddress dstAddress = InetAddresses.forString(getAddressString(gre.getDst())); @@ -152,20 +169,9 @@ public class GreCustomizer extends AbstractInterfaceTypeCustomizer { getFutureJVpp().greAddDelTunnel(getGreTunnelRequest((byte) 0 /* is add */, srcAddress.getAddress(), dstAddress.getAddress(), outerFibId, isIpv6)); - TranslateUtils.getReplyForWrite(greAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(greAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Gre tunnel deleted successfully for: {}, gre: {}", swIfName, gre); // Remove interface from our interface context interfaceContext.removeName(swIfName, writeContext.getMappingContext()); } - - 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; - } } 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 index 64d262f23..e6b93dfee 100644 --- 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 @@ -19,11 +19,11 @@ 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.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.util.concurrent.CompletionStage; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection; @@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory; /** * Utility class providing Interconnection CUD support. */ -final class InterconnectionWriteUtils { +final class InterconnectionWriteUtils implements JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(InterconnectionWriteUtils.class); @@ -61,7 +61,7 @@ final class InterconnectionWriteUtils { void setInterconnection(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final Interconnection ic, final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { try { if (ic == null) { // TODO in case of update we should delete interconnection LOG.trace("Interconnection is not set. Skipping"); @@ -77,14 +77,14 @@ final class InterconnectionWriteUtils { } } catch (VppBaseCallException e) { LOG.warn("Failed to update bridge/xconnect based interconnection flags for: {}, interconnection: {}", - ifcName, ic); + ifcName, ic); throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass(), e); } } void deleteInterconnection(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final Interconnection ic, final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { try { if (ic == null) { // TODO in case of update we should delete interconnection LOG.trace("Interconnection is not set. Skipping"); @@ -98,7 +98,7 @@ final class InterconnectionWriteUtils { } } catch (VppBaseCallException e) { LOG.warn("Failed to delete bridge/xconnect based interconnection flags for: {}, interconnection: {}", - ifcName, ic); + ifcName, ic); throw new WriteFailedException(id, "Unable to delete Interconnection of type " + ic.getClass(), e); } } @@ -106,27 +106,27 @@ final class InterconnectionWriteUtils { private void setBridgeBasedL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final BridgeBased bb, final WriteContext writeContext, final byte enabled) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { LOG.debug("Setting bridge based interconnection(bridge-domain={}) for interface: {}", bb.getBridgeDomain(), - ifcName); + 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); + ifcName, bdName); byte bvi = bb.isBridgedVirtualInterface() - ? (byte) 1 - : (byte) 0; + ? (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)); - TranslateUtils.getReplyForWrite(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture(), id); + .swInterfaceSetL2Bridge(getL2BridgeRequest(swIfIndex, bdId, shg, bvi, enabled)); + getReplyForWrite(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName, bb); } @@ -145,19 +145,19 @@ final class InterconnectionWriteUtils { private void setXconnectBasedL2(final InstanceIdentifier id, final int swIfIndex, final String ifcName, final XconnectBased ic, final WriteContext writeContext, final byte enabled) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { 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); + "Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist", + ifcName, outSwIfIndex); final CompletionStage swInterfaceSetL2XconnectReplyCompletionStage = - futureJVppCore - .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, enabled)); - TranslateUtils.getReplyForWrite(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture(), id); + futureJVppCore + .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, enabled)); + getReplyForWrite(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName, ic); } 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 index be0c4af09..91861015c 100644 --- 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 @@ -18,11 +18,11 @@ package io.fd.honeycomb.translate.v3po.interfaces; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; 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; @@ -38,7 +38,8 @@ import org.slf4j.LoggerFactory; /** * Ietf interface write customizer that only caches interface objects for child writers */ -public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer { +public class InterfaceCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); private final NamingContext interfaceContext; @@ -52,7 +53,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Interface dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { try { setInterface(id, dataAfter, writeContext); @@ -67,7 +68,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri @Nonnull final Interface dataBefore, @Nonnull final Interface dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { try { updateInterface(id, dataBefore, dataAfter, writeContext); @@ -86,41 +87,45 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri private void setInterface(final InstanceIdentifier id, final Interface swIf, final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { 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 VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { setInterfaceFlags(id, swIfName, interfaceContext.getIndex(swIfName, writeContext.getMappingContext()), - swIf.isEnabled() ? (byte) 1 : (byte) 0); + swIf.isEnabled() + ? (byte) 1 + : (byte) 0); } private void updateInterface(final InstanceIdentifier id, final Interface dataBefore, final Interface dataAfter, final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { 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 VppBaseCallException, WriteTimeoutException { - final CompletionStage swInterfaceSetFlagsReplyFuture = getFutureJVpp().swInterfaceSetFlags( - getSwInterfaceSetFlagsInput(swIfIndex, enabled, (byte) 0 /* deleted */)); + throws VppBaseCallException, WriteTimeoutException { + final CompletionStage swInterfaceSetFlagsReplyFuture = + getFutureJVpp().swInterfaceSetFlags( + getSwInterfaceSetFlagsInput(swIfIndex, enabled, (byte) 0 /* deleted */)); LOG.debug("Updating interface flags for: {}, index: {}, enabled: {}", swIfName, swIfIndex, enabled); - TranslateUtils.getReplyForWrite(swInterfaceSetFlagsReplyFuture.toCompletableFuture(), id); + 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) { + private SwInterfaceSetFlags getSwInterfaceSetFlagsInput(final int swIfIndex, final byte enabled, + final byte deleted) { final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags(); swInterfaceSetFlags.swIfIndex = swIfIndex; swInterfaceSetFlags.adminUpDown = enabled; 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 index 18100e218..002cc4c77 100644 --- 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 @@ -19,8 +19,8 @@ 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.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import java.net.InetAddress; @@ -31,14 +31,14 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces. import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ProxyArp; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.openvpp.jvpp.VppBaseCallException; -import org.openvpp.jvpp.core.future.FutureJVppCore; import org.openvpp.jvpp.core.dto.ProxyArpAddDel; import org.openvpp.jvpp.core.dto.ProxyArpAddDelReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCustomizer { +public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCustomizer, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class); private final NamingContext interfaceContext; @@ -49,7 +49,8 @@ public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCu } @Override - public void writeCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataAfter, @Nonnull WriteContext writeContext) throws WriteFailedException { + public void writeCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { final String swIfName = id.firstKeyOf(Interface.class).getName(); try { @@ -93,7 +94,7 @@ public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCu dstAddress.getAddress(), vrfId)); final ProxyArpAddDelReply reply = - TranslateUtils.getReplyForWrite(proxyArpAddDelReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(proxyArpAddDelReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Proxy ARP setting applied, with reply context:", reply.context); } 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 index ebaad456b..b17cfc820 100644 --- 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 @@ -16,15 +16,14 @@ package io.fd.honeycomb.translate.v3po.interfaces; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte; - import com.google.common.base.Preconditions; import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils; import io.fd.honeycomb.translate.v3po.util.TagRewriteOperation; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; @@ -49,7 +48,8 @@ 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 { +public class RewriteCustomizer extends FutureJVppCustomizer + implements WriterCustomizer, ByteDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class); private final NamingContext interfaceContext; @@ -80,14 +80,14 @@ public class RewriteCustomizer extends FutureJVppCustomizer implements WriterCus private void setTagRewrite(final InstanceIdentifier id, final String ifname, final Rewrite rewrite, final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { 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)); - TranslateUtils.getReplyForWrite(replyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(replyCompletionStage.toCompletableFuture(), id); LOG.debug("Tag rewrite for interface {}(id=) set successfully: {}", ifname, swIfIndex, rewrite); } 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 index 51bf31d07..44fd8807c 100644 --- 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 @@ -16,13 +16,13 @@ package io.fd.honeycomb.translate.v3po.interfaces; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; 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; @@ -35,7 +35,7 @@ import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class RoutingCustomizer extends FutureJVppCustomizer implements WriterCustomizer { +public class RoutingCustomizer extends FutureJVppCustomizer implements WriterCustomizer, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(RoutingCustomizer.class); private final NamingContext interfaceContext; @@ -48,7 +48,7 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements WriterCus @Override public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { final String ifName = id.firstKeyOf(Interface.class).getName(); try { @@ -63,7 +63,7 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements WriterCus public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Routing dataBefore, @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { final String ifName = id.firstKeyOf(Interface.class).getName(); try { @@ -86,13 +86,14 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements WriterCus LOG.debug("Setting routing for interface: {}, {}. Routing: {}", name, swIfc, rt); int vrfId = (rt != null) - ? rt.getVrfId().intValue() - : 0; + ? rt.getVrfId().intValue() + : 0; if (vrfId != 0) { final CompletionStage swInterfaceSetTableReplyCompletionStage = - getFutureJVpp().swInterfaceSetTable(getInterfaceSetTableRequest(swIfc, (byte) 0, /* isIpv6 */ vrfId)); - TranslateUtils.getReplyForWrite(swInterfaceSetTableReplyCompletionStage.toCompletableFuture(), id); + getFutureJVpp() + .swInterfaceSetTable(getInterfaceSetTableRequest(swIfc, (byte) 0, /* isIpv6 */ vrfId)); + getReplyForWrite(swInterfaceSetTableReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Routing set successfully for interface: {}, {}, routing: {}", name, swIfc, rt); } } 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 index 10dd60841..f2c1cc418 100644 --- 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 @@ -19,17 +19,16 @@ package io.fd.honeycomb.translate.v3po.interfaces; import static com.google.common.base.Preconditions.checkState; import static io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils.getNumberOfTags; import static io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils.getSubInterfaceName; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte; import com.google.common.base.Preconditions; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; -import java.util.List; import java.util.concurrent.CompletionStage; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -60,12 +59,13 @@ import org.slf4j.LoggerFactory; * Equivalent of invoking {@code vppclt create subif} command. */ public class SubInterfaceCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer { + 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) { + public SubInterfaceCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { super(futureJVppCore); this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); } @@ -73,7 +73,7 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer @Override public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final SubInterface dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { final String superIfName = id.firstKeyOf(Interface.class).getName(); try { createSubInterface(id, superIfName, dataAfter, writeContext); @@ -89,15 +89,15 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer WriteTimeoutException { final int superIfIndex = interfaceContext.getIndex(superIfName, writeContext.getMappingContext()); final CompletionStage createSubifReplyCompletionStage = - getFutureJVpp().createSubif(getCreateSubifRequest(subInterface, superIfIndex)); + getFutureJVpp().createSubif(getCreateSubifRequest(subInterface, superIfIndex)); final CreateSubifReply reply = - TranslateUtils.getReplyForWrite(createSubifReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(createSubifReplyCompletionStage.toCompletableFuture(), id); setInterfaceState(id, reply.swIfIndex, booleanToByte(subInterface.isEnabled())); interfaceContext.addName(reply.swIfIndex, - getSubInterfaceName(superIfName, Math.toIntExact(subInterface.getIdentifier())), - writeContext.getMappingContext()); + getSubInterfaceName(superIfName, Math.toIntExact(subInterface.getIdentifier())), + writeContext.getMappingContext()); LOG.debug("Sub interface created successfully for: {}, subInterface: {}", superIfName, subInterface); } @@ -124,7 +124,7 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer // TODO HONEYCOMB-183 match should be mandatory final MatchType matchType = subInterface.getMatch().getMatchType(); request.exactMatch = - booleanToByte(matchType instanceof VlanTagged && ((VlanTagged) matchType).isMatchExactTags()); + booleanToByte(matchType instanceof VlanTagged && ((VlanTagged) matchType).isMatchExactTags()); request.defaultSub = booleanToByte(matchType instanceof Default); if (numberOfTags > 0) { @@ -167,41 +167,41 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final SubInterface dataBefore, @Nonnull final SubInterface dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { final String subIfaceName = getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), - Math.toIntExact(dataAfter.getIdentifier())); + Math.toIntExact(dataAfter.getIdentifier())); try { setInterfaceState(id, interfaceContext.getIndex(subIfaceName, writeContext.getMappingContext()), - booleanToByte(dataAfter.isEnabled())); + booleanToByte(dataAfter.isEnabled())); } catch (VppBaseCallException e) { LOG.warn("Failed to update interface state for: interface if={}, enabled: {}", - subIfaceName, booleanToByte(dataAfter.isEnabled())); + subIfaceName, booleanToByte(dataAfter.isEnabled())); throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); } } private void setInterfaceState(final InstanceIdentifier id, final int swIfIndex, final byte enabled) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags(); swInterfaceSetFlags.swIfIndex = swIfIndex; swInterfaceSetFlags.adminUpDown = enabled; final CompletionStage swInterfaceSetFlagsReplyFuture = - getFutureJVpp().swInterfaceSetFlags(swInterfaceSetFlags); + getFutureJVpp().swInterfaceSetFlags(swInterfaceSetFlags); LOG.debug("Updating interface state for interface if={}, enabled: {}", swIfIndex, enabled); SwInterfaceSetFlagsReply reply = - TranslateUtils.getReplyForWrite(swInterfaceSetFlagsReplyFuture.toCompletableFuture(), id); + getReplyForWrite(swInterfaceSetFlagsReplyFuture.toCompletableFuture(), id); LOG.debug("Interface state updated successfully for interface index: {}, enabled: {}, ctxId: {}", - swIfIndex, enabled, reply.context); + swIfIndex, enabled, reply.context); } @Override public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final SubInterface dataBefore, @Nonnull final WriteContext writeContext) - throws WriteFailedException.DeleteFailedException { + 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 index cfb78499a..8bccb7a99 100644 --- 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 @@ -16,11 +16,11 @@ package io.fd.honeycomb.translate.v3po.interfaces; -import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.spi.write.WriterCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.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; 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 index ba3c99ca8..3dec19803 100644 --- 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 @@ -17,10 +17,11 @@ package io.fd.honeycomb.translate.v3po.interfaces; import io.fd.honeycomb.translate.v3po.util.AbstractInterfaceTypeCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.v3po.util.MacTranslator; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; +import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import java.util.concurrent.CompletionStage; import javax.annotation.Nonnull; @@ -40,7 +41,7 @@ import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class TapCustomizer extends AbstractInterfaceTypeCustomizer { +public class TapCustomizer extends AbstractInterfaceTypeCustomizer implements MacTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class); private final NamingContext interfaceContext; @@ -57,8 +58,8 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer { @Override protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Tap dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { + @Nonnull final WriteContext writeContext) + throws WriteFailedException { final String ifcName = id.firstKeyOf(Interface.class).getName(); try { createTap(id, ifcName, dataAfter, writeContext); @@ -71,7 +72,7 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer { @Override public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Tap dataBefore, @Nonnull final Tap dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { final String ifcName = id.firstKeyOf(Interface.class).getName(); final int index; @@ -92,7 +93,7 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer { @Override public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Tap dataBefore, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { final String ifcName = id.firstKeyOf(Interface.class).getName(); final int index; @@ -114,31 +115,33 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer { final WriteContext writeContext) throws VppBaseCallException, WriteTimeoutException { LOG.debug("Setting tap interface: {}. Tap: {}", swIfName, tap); final CompletionStage tapConnectFuture = - getFutureJVpp().tapConnect(getTapConnectRequest(tap.getTapName(), tap.getMac(), tap.getDeviceInstance())); + getFutureJVpp() + .tapConnect(getTapConnectRequest(tap.getTapName(), tap.getMac(), tap.getDeviceInstance())); final TapConnectReply reply = - TranslateUtils.getReplyForWrite(tapConnectFuture.toCompletableFuture(), id); + getReplyForWrite(tapConnectFuture.toCompletableFuture(), id); 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 tap) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { LOG.debug("Modifying tap interface: {}. Tap: {}", swIfName, tap); final CompletionStage vxlanAddDelTunnelReplyCompletionStage = - getFutureJVpp().tapModify(getTapModifyRequest(tap.getTapName(), index, tap.getMac(), tap.getDeviceInstance())); - TranslateUtils.getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + getFutureJVpp() + .tapModify(getTapModifyRequest(tap.getTapName(), index, tap.getMac(), tap.getDeviceInstance())); + getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Tap modified successfully for: {}, tap: {}", swIfName, tap); } private void deleteTap(final InstanceIdentifier id, final String swIfName, final int index, final Tap dataBefore, final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { LOG.debug("Deleting tap interface: {}. Tap: {}", swIfName, dataBefore); final CompletionStage vxlanAddDelTunnelReplyCompletionStage = - getFutureJVpp().tapDelete(getTapDeleteRequest(index)); - TranslateUtils.getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + getFutureJVpp().tapDelete(getTapDeleteRequest(index)); + getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Tap deleted successfully for: {}, tap: {}", swIfName, dataBefore); // Remove deleted interface from interface context interfaceContext.removeName(swIfName, writeContext.getMappingContext()); @@ -148,15 +151,15 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer { final TapConnect tapConnect = new TapConnect(); tapConnect.tapName = tapName.getBytes(); - if(mac == null) { + if (mac == null) { tapConnect.useRandomMac = 1; tapConnect.macAddress = new byte[6]; } else { tapConnect.useRandomMac = 0; - tapConnect.macAddress = TranslateUtils.parseMac(mac.getValue()); + tapConnect.macAddress = parseMac(mac.getValue()); } - if(deviceInstance == null) { + if (deviceInstance == null) { tapConnect.renumber = 0; } else { tapConnect.renumber = 1; @@ -166,20 +169,21 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer { return tapConnect; } - private TapModify getTapModifyRequest(final String tapName, final int swIndex, final PhysAddress mac, final Long deviceInstance) { + 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) { + if (mac == null) { tapConnect.useRandomMac = 1; tapConnect.macAddress = new byte[6]; } else { tapConnect.useRandomMac = 0; - tapConnect.macAddress = TranslateUtils.parseMac(mac.getValue()); + tapConnect.macAddress = parseMac(mac.getValue()); } - if(deviceInstance == null) { + if (deviceInstance == null) { tapConnect.renumber = 0; } else { tapConnect.renumber = 1; 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 index d4e734da1..b66afb2b5 100644 --- 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 @@ -18,10 +18,11 @@ package io.fd.honeycomb.translate.v3po.interfaces; import com.google.common.base.Preconditions; import io.fd.honeycomb.translate.v3po.util.AbstractInterfaceTypeCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; +import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import java.util.concurrent.CompletionStage; import javax.annotation.Nonnull; @@ -44,7 +45,8 @@ import org.slf4j.LoggerFactory; /** * Writer Customizer responsible for passing vhost user interface CRD operations to VPP */ -public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer { +public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer + implements ByteDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class); private final NamingContext interfaceContext; @@ -61,7 +63,7 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer id, - @Nonnull final VhostUser dataAfter, @Nonnull final WriteContext writeContext) + @Nonnull final VhostUser dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException { final String swIfName = id.firstKeyOf(Interface.class).getName(); try { @@ -74,13 +76,13 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer id, final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { LOG.debug("Creating vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); final CompletionStage createVhostUserIfReplyCompletionStage = getFutureJVpp().createVhostUserIf(getCreateVhostUserIfRequest(vhostUser)); final CreateVhostUserIfReply reply = - TranslateUtils.getReplyForWrite(createVhostUserIfReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(createVhostUserIfReplyCompletionStage.toCompletableFuture(), id); 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()); @@ -88,7 +90,7 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer id, final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { LOG.debug("Updating vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); final CompletionStage modifyVhostUserIfReplyCompletionStage = getFutureJVpp() - .modifyVhostUserIf(getModifyVhostUserIfRequest(vhostUser, interfaceContext.getIndex(swIfName, writeContext.getMappingContext()))); + .modifyVhostUserIf(getModifyVhostUserIfRequest(vhostUser, + interfaceContext.getIndex(swIfName, writeContext.getMappingContext()))); - TranslateUtils.getReplyForWrite(modifyVhostUserIfReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(modifyVhostUserIfReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Vhost user interface updated successfully for: {}, vhostUser: {}", swIfName, vhostUser); } private ModifyVhostUserIf getModifyVhostUserIfRequest(final VhostUser vhostUser, final int swIfIndex) { ModifyVhostUserIf request = new ModifyVhostUserIf(); - request.isServer = TranslateUtils.booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())); + request.isServer = booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())); request.sockFilename = vhostUser.getSocket().getBytes(); // TODO HONEYCOMB-177 request.renumber = 0; @@ -150,12 +153,13 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer id, final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { LOG.debug("Deleting vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); final CompletionStage deleteVhostUserIfReplyCompletionStage = - getFutureJVpp().deleteVhostUserIf(getDeleteVhostUserIfRequest(interfaceContext.getIndex(swIfName, writeContext.getMappingContext()))); + getFutureJVpp().deleteVhostUserIf(getDeleteVhostUserIfRequest( + interfaceContext.getIndex(swIfName, writeContext.getMappingContext()))); - TranslateUtils.getReplyForWrite(deleteVhostUserIfReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(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()); 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 index 1513f7b15..d96ef3e34 100644 --- 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 @@ -21,8 +21,8 @@ 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.v3po.util.AbstractInterfaceTypeCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; @@ -42,7 +42,7 @@ import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer { +public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer implements JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class); @@ -64,7 +64,7 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer { @Override protected final void writeInterface(@Nonnull final InstanceIdentifier id, @Nonnull final Vxlan dataAfter, - @Nonnull final WriteContext writeContext) + @Nonnull final WriteContext writeContext) throws WriteFailedException { final String swIfName = id.firstKeyOf(Interface.class).getName(); try { @@ -98,7 +98,9 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer { private void createVxlanTunnel(final InstanceIdentifier id, final String swIfName, final Vxlan vxlan, final WriteContext writeContext) throws VppBaseCallException, WriteTimeoutException { - final byte isIpv6 = (byte) (isIpv6(vxlan) ? 1 : 0); + final byte isIpv6 = (byte) (isIpv6(vxlan) + ? 1 + : 0); final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc())); final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst())); @@ -111,7 +113,7 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer { dstAddress.getAddress(), encapVrfId, -1, vni, isIpv6)); final VxlanAddDelTunnelReply reply = - TranslateUtils.getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); 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) @@ -123,7 +125,7 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer { // 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); + reply.swIfIndex, formerName, swIfName); interfaceNamingContext.removeName(formerName, writeContext.getMappingContext()); } @@ -142,22 +144,26 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer { 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()); + vxlan.getDst()); return true; } else { checkArgument(vxlan.getDst().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", vxlan.getSrc(), - vxlan.getDst()); + vxlan.getDst()); return false; } } private String getAddressString(final IpAddress addr) { - return addr.getIpv4Address() == null ? addr.getIpv6Address().getValue() : addr.getIpv4Address().getValue(); + 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 VppBaseCallException, WriteTimeoutException { - final byte isIpv6 = (byte) (isIpv6(vxlan) ? 1 : 0); + final byte isIpv6 = (byte) (isIpv6(vxlan) + ? 1 + : 0); final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc())); final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst())); @@ -169,7 +175,7 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer { getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 0 /* is add */, srcAddress.getAddress(), dstAddress.getAddress(), encapVrfId, -1, vni, isIpv6)); - TranslateUtils.getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Vxlan tunnel deleted successfully for: {}, vxlan: {}", swIfName, vxlan); final int index = interfaceNamingContext.getIndex(swIfName, writeContext.getMappingContext()); @@ -182,8 +188,8 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer { } 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 int encapVrfId, + final int decapNextIndex, final int vni, final byte isIpv6) { final VxlanAddDelTunnel vxlanAddDelTunnel = new VxlanAddDelTunnel(); vxlanAddDelTunnel.isAdd = isAdd; vxlanAddDelTunnel.srcAddress = srcAddr; 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 index 699c33d21..aeba262db 100644 --- 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 @@ -21,11 +21,11 @@ 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.v3po.util.AbstractInterfaceTypeCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.net.InetAddress; import java.util.concurrent.CompletionStage; import javax.annotation.Nonnull; @@ -42,7 +42,7 @@ import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer { +public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer implements JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class); private final NamingContext interfaceNamingContext; @@ -62,8 +62,9 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer id, @Nonnull final VxlanGpe dataAfter, - @Nonnull final WriteContext writeContext) + 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(); try { @@ -75,7 +76,8 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer id, @Nonnull final VxlanGpe dataBefore, + 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, @@ -83,7 +85,8 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer id, @Nonnull final VxlanGpe dataBefore, + 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(); @@ -97,8 +100,10 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer id, final String swIfName, final VxlanGpe vxlanGpe, final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { - final byte isIpv6 = (byte) (isIpv6(vxlanGpe) ? 1 : 0); + throws VppBaseCallException, WriteTimeoutException { + final byte isIpv6 = (byte) (isIpv6(vxlanGpe) + ? 1 + : 0); final InetAddress Local = InetAddresses.forString(getAddressString(vxlanGpe.getLocal())); final InetAddress Remote = InetAddresses.forString(getAddressString(vxlanGpe.getRemote())); @@ -110,15 +115,15 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer VxlanGpeAddDelTunnelReplyCompletionStage = getFutureJVpp().vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 1 /* is add */, Local.getAddress(), - Remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); + Remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); final VxlanGpeAddDelTunnelReply reply = - TranslateUtils.getReplyForWrite(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); 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); + reply.swIfIndex, formerName, swIfName); interfaceNamingContext.removeName(formerName, writeContext.getMappingContext()); } @@ -135,24 +140,30 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer id, final String swIfName, final VxlanGpe vxlanGpe, final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { - final byte isIpv6 = (byte) (isIpv6(vxlanGpe) ? 1 : 0); + throws VppBaseCallException, WriteTimeoutException { + final byte isIpv6 = (byte) (isIpv6(vxlanGpe) + ? 1 + : 0); final InetAddress local = InetAddresses.forString(getAddressString(vxlanGpe.getLocal())); final InetAddress remote = InetAddresses.forString(getAddressString(vxlanGpe.getRemote())); @@ -163,10 +174,11 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer VxlanGpeAddDelTunnelReplyCompletionStage = - getFutureJVpp().vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 0 /* is delete */, local.getAddress(), - remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); + getFutureJVpp() + .vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 0 /* is delete */, local.getAddress(), + remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); - TranslateUtils.getReplyForWrite(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); final int index = interfaceNamingContext.getIndex(swIfName, writeContext.getMappingContext()); // Mark this interface as disabled to not include it in operational reads @@ -177,9 +189,11 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer type of access control list entry */ -abstract class AbstractAceWriter implements AceWriter { +abstract class AbstractAceWriter implements AceWriter, JvppReplyConsumer { // TODO: HONEYCOMB-181 minimise memory used by classify tables (we create a lot of them to make ietf-acl model // mapping more convenient): @@ -60,7 +60,7 @@ abstract class AbstractAceWriter implements AceWriter { static final int VLAN_TAG_LEN = 4; private static final Collector SINGLE_ITEM_COLLECTOR = - RWUtils.singleItemCollector(); + RWUtils.singleItemCollector(); private final FutureJVppCore futureJVppCore; @@ -107,9 +107,9 @@ abstract class AbstractAceWriter implements AceWriter { @Override public final void write(@Nonnull final InstanceIdentifier id, @Nonnull final List aces, @Nonnull final InputAclSetInterface request, @Nonnegative final int vlanTags) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { final PacketHandling action = aces.stream().map(ace -> ace.getActions().getPacketHandling()).distinct() - .collect(SINGLE_ITEM_COLLECTOR); + .collect(SINGLE_ITEM_COLLECTOR); checkArgument(vlanTags >= 0 && vlanTags <= 2, "Number of vlan tags %s is not in [0,2] range"); @@ -118,29 +118,29 @@ abstract class AbstractAceWriter implements AceWriter { // Create table + session per entry final ClassifyAddDelTable ctRequest = - createClassifyTable(action, (T) ace.getMatches().getAceType(), nextTableIndex, vlanTags); + createClassifyTable(action, (T) ace.getMatches().getAceType(), nextTableIndex, vlanTags); nextTableIndex = createClassifyTable(id, ctRequest); createClassifySession(id, - createClassifySession(action, (T) ace.getMatches().getAceType(), nextTableIndex, vlanTags)); + createClassifySession(action, (T) ace.getMatches().getAceType(), nextTableIndex, vlanTags)); } setClassifyTable(request, nextTableIndex); } private int createClassifyTable(@Nonnull final InstanceIdentifier id, @Nonnull final ClassifyAddDelTable request) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { final CompletionStage cs = futureJVppCore.classifyAddDelTable(request); - final ClassifyAddDelTableReply reply = TranslateUtils.getReplyForWrite(cs.toCompletableFuture(), id); + final ClassifyAddDelTableReply reply = getReplyForWrite(cs.toCompletableFuture(), id); return reply.newTableIndex; } private void createClassifySession(@Nonnull final InstanceIdentifier id, @Nonnull final ClassifyAddDelSession request) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { final CompletionStage cs = futureJVppCore.classifyAddDelSession(request); - TranslateUtils.getReplyForWrite(cs.toCompletableFuture(), id); + getReplyForWrite(cs.toCompletableFuture(), id); } protected ClassifyAddDelTable createClassifyTable(@Nonnull final PacketHandling action, final int nextTableIndex) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriter.java index f6bb9c879..395058399 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriter.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriter.java @@ -17,7 +17,7 @@ package io.fd.honeycomb.translate.v3po.interfaces.acl; import com.google.common.annotations.VisibleForTesting; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.MacTranslator; import java.util.List; 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; @@ -29,7 +29,7 @@ import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -final class AceEthWriter extends AbstractAceWriter { +final class AceEthWriter extends AbstractAceWriter implements MacTranslator { @VisibleForTesting static final int MATCH_N_VECTORS = 1; @@ -54,10 +54,10 @@ final class AceEthWriter extends AbstractAceWriter { if (aceEth.getDestinationMacAddressMask() != null) { aceIsEmpty = false; final String macAddress = aceEth.getDestinationMacAddressMask().getValue(); - final List parts = TranslateUtils.COLON_SPLITTER.splitToList(macAddress); + final List parts = COLON_SPLITTER.splitToList(macAddress); int i = 0; for (String part : parts) { - request.mask[i++] = TranslateUtils.parseHexByte(part); + request.mask[i++] = parseHexByte(part); } } else if (aceEth.getDestinationMacAddress() != null) { aceIsEmpty = false; @@ -71,10 +71,10 @@ final class AceEthWriter extends AbstractAceWriter { if (aceEth.getSourceMacAddressMask() != null) { aceIsEmpty = false; final String macAddress = aceEth.getSourceMacAddressMask().getValue(); - final List parts = TranslateUtils.COLON_SPLITTER.splitToList(macAddress); + final List parts = COLON_SPLITTER.splitToList(macAddress); int i = 6; for (String part : parts) { - request.mask[i++] = TranslateUtils.parseHexByte(part); + request.mask[i++] = parseHexByte(part); } } else if (aceEth.getSourceMacAddress() != null) { aceIsEmpty = false; @@ -85,7 +85,7 @@ final class AceEthWriter extends AbstractAceWriter { if (aceIsEmpty) { throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceEth.toString())); + String.format("Ace %s does not define packet field match values", aceEth.toString())); } request.skipNVectors = 0; @@ -108,26 +108,27 @@ final class AceEthWriter extends AbstractAceWriter { if (aceEth.getDestinationMacAddress() != null) { noMatch = false; final String macAddress = aceEth.getDestinationMacAddress().getValue(); - final List parts = TranslateUtils.COLON_SPLITTER.splitToList(macAddress); + final List parts = COLON_SPLITTER.splitToList(macAddress); int i = 0; for (String part : parts) { - request.match[i++] = TranslateUtils.parseHexByte(part); + request.match[i++] = parseHexByte(part); } } if (aceEth.getSourceMacAddress() != null) { noMatch = false; final String macAddress = aceEth.getSourceMacAddress().getValue(); - final List parts = TranslateUtils.COLON_SPLITTER.splitToList(macAddress); + final List parts = COLON_SPLITTER.splitToList(macAddress); int i = 6; for (String part : parts) { - request.match[i++] = TranslateUtils.parseHexByte(part); + request.match[i++] = parseHexByte(part); } } if (noMatch) { throw new IllegalArgumentException( - String.format("Ace %s does not define neither source nor destination MAC address", aceEth.toString())); + 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); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4Writer.java index cb232ed3e..b19c754e5 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4Writer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4Writer.java @@ -17,10 +17,10 @@ package io.fd.honeycomb.translate.v3po.interfaces.acl; import static com.google.common.base.Preconditions.checkArgument; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.ipv4AddressNoZoneToArray; import com.google.common.annotations.VisibleForTesting; import com.google.common.primitives.Ints; +import io.fd.honeycomb.translate.v3po.util.Ipv4Translator; 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.matches.ace.type.AceIp; @@ -33,7 +33,7 @@ import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -final class AceIp4Writer extends AbstractAceWriter { +final class AceIp4Writer extends AbstractAceWriter implements Ipv4Translator { @VisibleForTesting static final int MATCH_N_VECTORS = 3; // number of 16B vectors @@ -63,7 +63,8 @@ final class AceIp4Writer extends AbstractAceWriter { return toByteMask(prefixLength); } - private static byte[] toMatchValue(final Ipv4Prefix ipv4Prefix) { + // static removed, cant use default from static content + private byte[] toMatchValue(final Ipv4Prefix ipv4Prefix) { final String[] split = ipv4Prefix.getValue().split("/"); final byte[] addressBytes = ipv4AddressNoZoneToArray(split[0]); final byte[] mask = toByteMask(Byte.valueOf(split[1])); @@ -111,19 +112,19 @@ final class AceIp4Writer extends AbstractAceWriter { if (ipVersion.getSourceIpv4Network() != null) { aceIsEmpty = false; System.arraycopy(toByteMask(ipVersion.getSourceIpv4Network()), 0, request.mask, baseOffset + SRC_IP_OFFSET, - IP4_LEN); + IP4_LEN); } if (ipVersion.getDestinationIpv4Network() != null) { aceIsEmpty = false; System - .arraycopy(toByteMask(ipVersion.getDestinationIpv4Network()), 0, request.mask, - baseOffset + DST_IP_OFFSET, IP4_LEN); + .arraycopy(toByteMask(ipVersion.getDestinationIpv4Network()), 0, request.mask, + baseOffset + DST_IP_OFFSET, IP4_LEN); } if (aceIsEmpty) { throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); + String.format("Ace %s does not define packet field match values", aceIp.toString())); } LOG.debug("ACE action={}, rule={} translated to table={}.", action, aceIp, request); @@ -147,7 +148,7 @@ final class AceIp4Writer extends AbstractAceWriter { if (aceIp.getProtocol() != null) { request.match[baseOffset + IP_VERSION_OFFSET] = - (byte) (IP_VERSION_MASK & (aceIp.getProtocol().intValue() << 4)); + (byte) (IP_VERSION_MASK & (aceIp.getProtocol().intValue() << 4)); } if (aceIp.getDscp() != null) { @@ -166,20 +167,21 @@ final class AceIp4Writer extends AbstractAceWriter { if (ipVersion.getSourceIpv4Network() != null) { noMatch = false; System - .arraycopy(toMatchValue(ipVersion.getSourceIpv4Network()), 0, request.match, baseOffset + SRC_IP_OFFSET, - IP4_LEN); + .arraycopy(toMatchValue(ipVersion.getSourceIpv4Network()), 0, request.match, + baseOffset + SRC_IP_OFFSET, + IP4_LEN); } if (ipVersion.getDestinationIpv4Network() != null) { noMatch = false; System.arraycopy(toMatchValue(ipVersion.getDestinationIpv4Network()), 0, request.match, - baseOffset + DST_IP_OFFSET, - IP4_LEN); + baseOffset + DST_IP_OFFSET, + IP4_LEN); } if (noMatch) { throw new IllegalArgumentException( - String.format("Ace %s does not define packet field match values", aceIp.toString())); + String.format("Ace %s does not define packet field match values", aceIp.toString())); } LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request); 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 index 3f75d6729..f337cebd0 100644 --- 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 @@ -20,7 +20,7 @@ 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.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; @@ -54,7 +54,7 @@ import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public final class IetfAClWriter { +public final class IetfAClWriter implements JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(IetfAClWriter.class); private final FutureJVppCore jvpp; @@ -75,12 +75,12 @@ public final class IetfAClWriter { // ietf-acl updates are handled first, so we use writeContext.readAfter final Optional - aclOptional = writeContext.readAfter(AclWriter.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))); + aclOptional = writeContext.readAfter(AclWriter.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(); + acl = aclOptional.get(); final AccessListEntries accessListEntries = acl.getAccessListEntries(); checkArgument(accessListEntries != null, "access list entries not configured"); @@ -89,13 +89,13 @@ public final class IetfAClWriter { } void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex) - throws WriteTimeoutException, WriteFailedException.DeleteFailedException { + throws WriteTimeoutException, WriteFailedException.DeleteFailedException { final ClassifyTableByInterface request = new ClassifyTableByInterface(); request.swIfIndex = swIfIndex; try { final CompletionStage cs = jvpp.classifyTableByInterface(request); - final ClassifyTableByInterfaceReply reply = TranslateUtils.getReplyForWrite(cs.toCompletableFuture(), id); + final ClassifyTableByInterfaceReply reply = getReplyForWrite(cs.toCompletableFuture(), id); // We unassign and remove all ACL-related classify tables for given interface (we assume we are the only // classify table manager) @@ -112,7 +112,7 @@ public final class IetfAClWriter { private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, final ClassifyTableByInterfaceReply currentState) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { final InputAclSetInterface request = new InputAclSetInterface(); request.isAdd = 0; request.swIfIndex = currentState.swIfIndex; @@ -120,12 +120,12 @@ public final class IetfAClWriter { request.ip4TableIndex = currentState.ip4TableId; request.ip6TableIndex = currentState.ip6TableId; final CompletionStage inputAclSetInterfaceReplyCompletionStage = - jvpp.inputAclSetInterface(request); - TranslateUtils.getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); + jvpp.inputAclSetInterface(request); + getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); } private void removeClassifyTable(@Nonnull final InstanceIdentifier id, final int tableIndex) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { if (tableIndex == -1) { return; // classify table id is absent @@ -133,23 +133,23 @@ public final class IetfAClWriter { final ClassifyAddDelTable request = new ClassifyAddDelTable(); request.tableIndex = tableIndex; final CompletionStage cs = jvpp.classifyAddDelTable(request); - TranslateUtils.getReplyForWrite(cs.toCompletableFuture(), id); + getReplyForWrite(cs.toCompletableFuture(), id); } void write(@Nonnull final InstanceIdentifier id, final int swIfIndex, @Nonnull final List acls, @Nonnull final WriteContext writeContext) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { write(id, swIfIndex, acls, writeContext, 0); } void write(@Nonnull final InstanceIdentifier id, final int swIfIndex, @Nonnull final List acls, @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { // filter ACE entries and group by AceType final Map> acesByType = acls.stream() - .flatMap(acl -> aclToAceStream(acl, writeContext)) - .collect(Collectors.groupingBy(AclType::fromAce)); + .flatMap(acl -> aclToAceStream(acl, writeContext)) + .collect(Collectors.groupingBy(AclType::fromAce)); final InputAclSetInterface request = new InputAclSetInterface(); request.isAdd = 1; @@ -173,9 +173,8 @@ public final class IetfAClWriter { } final CompletionStage inputAclSetInterfaceReplyCompletionStage = - jvpp.inputAclSetInterface(request); - TranslateUtils.getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); - + jvpp.inputAclSetInterface(request); + getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); } private enum AclType { 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 index 574a42eb5..8ab5b6b62 100644 --- 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 @@ -45,7 +45,8 @@ import org.slf4j.LoggerFactory; /** * Customizer for writing {@link Address} */ -public class Ipv4AddressCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer { +public class Ipv4AddressCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, Ipv4Writer { private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressCustomizer.class); private final NamingContext interfaceContext; @@ -131,8 +132,8 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer implements ListW final DottedQuad netmask = subnet.getNetmask(); checkNotNull(netmask, "netmask value should not be null"); - final byte subnetLength = Ipv4WriteUtils.getSubnetMaskLength(netmask.getValue()); - Ipv4WriteUtils.addDelAddress(getFutureJVpp(), add, id, interfaceIndex, address.getIp(), subnetLength); + final byte subnetLength = getSubnetMaskLength(netmask.getValue()); + addDelAddress(getFutureJVpp(), add, id, interfaceIndex, address.getIp(), subnetLength); } catch (VppBaseCallException e) { LOG.warn("Failed to set Subnet(subnet-mask) for interface: {}(id={}). Subnet: {}, address: {}", interfaceName, interfaceIndex, subnet, address); @@ -148,7 +149,7 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer implements ListW LOG.debug("Setting Subnet(prefix-length) for interface: {}(id={}). Subnet: {}, address: {}", interfaceName, interfaceIndex, subnet, address); - Ipv4WriteUtils.addDelAddress(getFutureJVpp(), add, id, interfaceIndex, address.getIp(), + addDelAddress(getFutureJVpp(), add, id, interfaceIndex, address.getIp(), subnet.getPrefixLength().byteValue()); LOG.debug("Subnet(prefix-length) set successfully for interface: {}(id={}). Subnet: {}, address: {}", 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 index 72d8277fc..ab25970e7 100644 --- 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 @@ -20,14 +20,16 @@ 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.v3po.util.AddressTranslator; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; 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; @@ -45,7 +47,8 @@ import org.slf4j.LoggerFactory; * Customizer for writing {@link Neighbor} for {@link Ipv4}. */ public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer { + implements ListWriterCustomizer, ByteDataTranslator, AddressTranslator, + JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); @@ -119,15 +122,15 @@ public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer IpNeighborAddDel request = new IpNeighborAddDel(); - request.isAdd = TranslateUtils.booleanToByte(add); + request.isAdd = booleanToByte(add); request.isIpv6 = 0; request.isStatic = 1; - request.dstAddress = TranslateUtils.ipv4AddressNoZoneToArray(data.getIp()); - request.macAddress = TranslateUtils.parseMac(data.getLinkLayerAddress().getValue()); + 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 - TranslateUtils.getReplyForWrite(getFutureJVpp().ipNeighborAddDel(request).toCompletableFuture(), id); + 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/Ipv4WriteUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4WriteUtils.java deleted file mode 100644 index 412030200..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4WriteUtils.java +++ /dev/null @@ -1,111 +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.v3po.util.TranslateUtils; -import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; -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; -import org.openvpp.jvpp.VppBaseCallException; -import org.openvpp.jvpp.core.dto.SwInterfaceAddDelAddress; -import org.openvpp.jvpp.core.dto.SwInterfaceAddDelAddressReply; -import org.openvpp.jvpp.core.future.FutureJVppCore; - -/** - * Utility class providing Ipv4 CUD support. - */ -// TODO HONEYCOMB-175 replace with interface with default methods or abstract class -public final class Ipv4WriteUtils { - - private static final int DOTTED_QUAD_MASK_LENGTH = 4; - private static final int IPV4_ADDRESS_PART_BITS_COUNT = 8; - private static final int NETMASK_PART_LIMIT = 256; // 2 power to 8 - - private Ipv4WriteUtils() { - throw new UnsupportedOperationException("This utility class cannot be instantiated"); - } - - static 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 VppBaseCallException, WriteTimeoutException { - checkArgument(prefixLength > 0, "Invalid prefix length"); - checkNotNull(address, "address should not be null"); - - final byte[] addressBytes = TranslateUtils.ipv4AddressNoZoneToArray(address); - - final CompletionStage swInterfaceAddDelAddressReplyCompletionStage = - futureJVppCore.swInterfaceAddDelAddress( - getSwInterfaceAddDelAddressRequest(ifaceId, TranslateUtils.booleanToByte(add) /* isAdd */, - (byte) 0 /* isIpv6 */, (byte) 0 /* delAll */, prefixLength, addressBytes)); - - TranslateUtils.getReplyForWrite(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture(), id); - } - - static 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 - */ - public static 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/Ipv4Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Writer.java new file mode 100644 index 000000000..a950d45de --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4Writer.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.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.v3po.util.ByteDataTranslator; +import io.fd.honeycomb.translate.v3po.util.Ipv4Translator; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; +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; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.SwInterfaceAddDelAddress; +import org.openvpp.jvpp.core.dto.SwInterfaceAddDelAddressReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; + +/** + * 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 VppBaseCallException, WriteTimeoutException { + 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 index 192906854..c04d14604 100644 --- 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 @@ -16,9 +16,9 @@ package io.fd.honeycomb.translate.v3po.interfaces.ip; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; 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; 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 index e0fa46335..3fbb493af 100644 --- 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 @@ -21,9 +21,9 @@ import static com.google.common.base.Preconditions.checkNotNull; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils; 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; @@ -45,7 +45,7 @@ import org.slf4j.LoggerFactory; * Write customizer for sub-interface {@link Address} */ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer { + implements ListWriterCustomizer, Ipv4Writer { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class); private final NamingContext interfaceContext; @@ -58,7 +58,7 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer @Override public void writeCurrentAttributes(InstanceIdentifier
id, Address dataAfter, WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { setAddress(true, id, dataAfter, writeContext); } @@ -66,12 +66,12 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer 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")); + new UnsupportedOperationException("Operation not supported")); } @Override public void deleteCurrentAttributes(InstanceIdentifier
id, Address dataBefore, WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { setAddress(false, id, dataBefore, writeContext); } @@ -98,26 +98,26 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); return SubInterfaceUtils - .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + .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 { + throws WriteFailedException { try { LOG.debug("Setting Subnet(subnet-mask) for sub-interface: {}(id={}). Subnet: {}, address: {}", - subInterfaceName, subInterfaceIndex, subnet, address); + subInterfaceName, subInterfaceIndex, subnet, address); final DottedQuad netmask = subnet.getNetmask(); checkNotNull(netmask, "netmask value should not be null"); - final byte subnetLength = Ipv4WriteUtils.getSubnetMaskLength(netmask.getValue()); - Ipv4WriteUtils.addDelAddress(getFutureJVpp(), add, id, subInterfaceIndex, address.getIp(), subnetLength); + final byte subnetLength = getSubnetMaskLength(netmask.getValue()); + addDelAddress(getFutureJVpp(), add, id, subInterfaceIndex, address.getIp(), subnetLength); } catch (VppBaseCallException e) { LOG.warn("Failed to set Subnet(subnet-mask) for sub-interface: {}(id={}). Subnet: {}, address: {}", - subInterfaceName, subInterfaceIndex, subnet, address); + subInterfaceName, subInterfaceIndex, subnet, address); throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass(), e); } } @@ -125,19 +125,19 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer 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 { + throws WriteFailedException { try { LOG.debug("Setting Subnet(prefix-length) for sub-interface: {}(id={}). Subnet: {}, address: {}", - subInterfaceName, subInterfaceIndex, subnet, address); + subInterfaceName, subInterfaceIndex, subnet, address); - Ipv4WriteUtils.addDelAddress(getFutureJVpp(), add, id, subInterfaceIndex, address.getIp(), - subnet.getPrefixLength().byteValue()); + 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); + subInterfaceName, subInterfaceIndex, subnet, address); } catch (VppBaseCallException e) { LOG.warn("Failed to set Subnet(prefix-length) for sub-interface: {}(id={}). Subnet: {}, address: {}", - subInterfaceName, subInterfaceIndex, subnet, address); + subInterfaceName, subInterfaceIndex, subnet, address); throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass(), e); } } 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 index 361113858..a314eaf14 100644 --- 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 @@ -21,7 +21,7 @@ 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.Ipv4WriteUtils; +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; @@ -32,7 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061 /** * Validator for detecting if there is an attempt to assign multiple addresses from same subnet */ -public class SubnetValidator { +public class SubnetValidator implements Ipv4Writer { /** * Checks whether data provided for writing are not in collision with already existing data @@ -60,7 +60,7 @@ public class SubnetValidator { .forConflictingData(conflictingPrefix, prefixLengthRegister.get(conflictingPrefix)); } - private static Function toPrefixLength() { + private Function toPrefixLength() { return (final Address address) -> { final Subnet subnet = address.getSubnet(); @@ -69,7 +69,7 @@ public class SubnetValidator { } if (address.getSubnet() instanceof Netmask) { - return (short) Ipv4WriteUtils.getSubnetMaskLength( + return (short) getSubnetMaskLength( checkNotNull(((Netmask) subnet).getNetmask(), "No netmask defined for %s", subnet) .getValue()); } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/AclCustomizer.java index 639b36651..04141ab12 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/AclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/AclCustomizer.java @@ -20,11 +20,11 @@ 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.ReaderCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; @@ -46,7 +46,7 @@ import org.slf4j.LoggerFactory; * Customizer for reading ACLs enabled on given interface. */ public class AclCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer, AclReader { + implements ReaderCustomizer, AclReader, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class); private final NamingContext interfaceContext; @@ -80,8 +80,8 @@ public class AclCustomizer extends FutureJVppCustomizer final ClassifyTableByInterface request = new ClassifyTableByInterface(); request.swIfIndex = interfaceContext.getIndex(interfaceKey.getName(), ctx.getMappingContext()); try { - final ClassifyTableByInterfaceReply reply = TranslateUtils - .getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); + 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())); 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 index abded50a3..fda8befe5 100644 --- 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 @@ -17,9 +17,9 @@ 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.v3po.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.v3po.util.NamingContext; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; @@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory; public class EthernetCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer { + implements ReaderCustomizer, InterfaceDataTranslator { private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class); private NamingContext interfaceContext; @@ -66,10 +66,10 @@ public class EthernetCustomizer extends FutureJVppCustomizer @Nonnull final ReadContext ctx) throws ReadFailedException { final InterfaceKey key = id.firstKeyOf(Interface.class); - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), - interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache()); + final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), + interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache(), LOG); - if(iface.linkMtu != 0) { + if (iface.linkMtu != 0) { builder.setMtu((int) iface.linkMtu); } 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 index 8b0a42068..fe672640a 100644 --- 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 @@ -17,14 +17,12 @@ package io.fd.honeycomb.translate.v3po.interfacesstate; import static com.google.common.base.Preconditions.checkState; -import static io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType; 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.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; @@ -35,8 +33,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. 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.rev150105.VppInterfaceStateAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.GreTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Gre; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.GreBuilder; import org.opendaylight.yangtools.concepts.Builder; @@ -51,7 +49,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class GreCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer { + implements ReaderCustomizer, InterfaceDataTranslator { private static final Logger LOG = LoggerFactory.getLogger(GreCustomizer.class); private NamingContext interfaceContext; @@ -80,7 +78,7 @@ public class GreCustomizer extends FutureJVppCustomizer try { 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)) { + if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, GreTunnel.class, LOG)) { return; } @@ -90,31 +88,32 @@ public class GreCustomizer extends FutureJVppCustomizer request.swIfIndex = index; final CompletionStage swInterfaceGreDetailsReplyDumpCompletionStage = - getFutureJVpp().greTunnelDump(request); + getFutureJVpp().greTunnelDump(request); final GreTunnelDetailsReplyDump reply = - TranslateUtils.getReplyForRead(swInterfaceGreDetailsReplyDumpCompletionStage.toCompletableFuture(), id); + 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); + "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()); + "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()); + new Ipv6Address(parseAddress(swInterfaceGreDetails.dstAddress).getHostAddress()); builder.setDst(new IpAddress(dstIpv6)); final Ipv6Address srcIpv6 = - new Ipv6Address(parseAddress(swInterfaceGreDetails.srcAddress).getHostAddress()); + new Ipv6Address(parseAddress(swInterfaceGreDetails.srcAddress).getHostAddress()); builder.setSrc(new IpAddress(srcIpv6)); } else { final byte[] dstBytes = Arrays.copyOfRange(swInterfaceGreDetails.dstAddress, 0, 4); @@ -128,7 +127,7 @@ public class GreCustomizer extends FutureJVppCustomizer LOG.debug("Gre tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); } catch (VppBaseCallException e) { LOG.warn("Failed to readCurrentAttributes for: {}", id, e); - throw new ReadFailedException( id, e ); + throw new ReadFailedException(id, e); } } 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 index 5dec9b426..acb7d855d 100644 --- 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 @@ -22,7 +22,6 @@ 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.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.util.Optional; import java.util.concurrent.CompletableFuture; import javax.annotation.Nonnull; @@ -43,7 +42,7 @@ import org.slf4j.LoggerFactory; /** * Utility class providing Interconnection read support. */ -final class InterconnectionReadUtils { +final class InterconnectionReadUtils implements InterfaceDataTranslator { private static final Logger LOG = LoggerFactory.getLogger(InterconnectionReadUtils.class); @@ -62,11 +61,11 @@ final class InterconnectionReadUtils { @Nullable Interconnection readInterconnection(@Nonnull final InstanceIdentifier id, @Nonnull final String ifaceName, @Nonnull final ReadContext ctx) - throws ReadFailedException { + throws ReadFailedException { final int ifaceId = interfaceContext.getIndex(ifaceName, ctx.getMappingContext()); - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(futureJVppCore, id, ifaceName, - ifaceId, ctx.getModificationCache()); + 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); @@ -78,7 +77,7 @@ final class InterconnectionReadUtils { // Set BVI if the bridgeDomainDetails.bviSwIfIndex == current sw if index final Optional bridgeDomainForInterface = - getBridgeDomainForInterface(dumpReply, bdForInterface.get().bdId); + 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) { @@ -112,7 +111,7 @@ final class InterconnectionReadUtils { } private BridgeDomainDetailsReplyDump getDumpReply(@Nonnull final InstanceIdentifier id) - throws ReadFailedException { + throws ReadFailedException { try { // 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?) @@ -121,8 +120,8 @@ final class InterconnectionReadUtils { request.bdId = -1; final CompletableFuture bdCompletableFuture = - futureJVppCore.bridgeDomainSwIfDump(request).toCompletableFuture(); - return TranslateUtils.getReplyForRead(bdCompletableFuture, id); + futureJVppCore.bridgeDomainSwIfDump(request).toCompletableFuture(); + return getReplyForRead(bdCompletableFuture, id); } catch (VppBaseCallException e) { throw new ReadFailedException(id, e); } 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 index d0baf003a..a85bfc09a 100644 --- 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 @@ -22,9 +22,9 @@ 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.DisabledInterfacesManager; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -54,12 +54,12 @@ import org.slf4j.LoggerFactory; * Customizer for reading ietf-interfaces:interfaces-state/interface. */ public class InterfaceCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer { + implements ListReaderCustomizer, ByteDataTranslator, + InterfaceDataTranslator { - private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); public static final String DUMPED_IFCS_CONTEXT_KEY = - InterfaceCustomizer.class.getName() + "dumpedInterfacesDuringGetAllIds"; - + InterfaceCustomizer.class.getName() + "dumpedInterfacesDuringGetAllIds"; + private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); private final NamingContext interfaceNamingContext; private final DisabledInterfacesManager interfaceDisableContext; @@ -71,6 +71,19 @@ public class InterfaceCustomizer extends FutureJVppCustomizer this.interfaceDisableContext = interfaceDisableContext; } + @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) { @@ -92,8 +105,8 @@ public class InterfaceCustomizer extends FutureJVppCustomizer } // Pass cached details from getAllIds to getDetails to avoid additional dumps - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, ifaceName, - index, ctx.getModificationCache()); + final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, ifaceName, + index, ctx.getModificationCache(), LOG); LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface); if (!isRegularInterface(iface)) { @@ -102,32 +115,23 @@ public class InterfaceCustomizer extends FutureJVppCustomizer } builder.setName(ifaceName); - builder.setType(InterfaceUtils.getInterfaceType(new String(iface.interfaceName).intern())); - builder.setIfIndex(InterfaceUtils.vppIfIndexToYang(iface.swIfIndex)); + builder.setType(getInterfaceType(new String(iface.interfaceName).intern())); + builder.setIfIndex(vppIfIndexToYang(iface.swIfIndex)); builder.setAdminStatus(1 == iface.adminUpDown - ? AdminStatus.Up - : AdminStatus.Down); + ? AdminStatus.Up + : AdminStatus.Down); builder.setOperStatus(1 == iface.linkUpDown - ? OperStatus.Up - : OperStatus.Down); + ? OperStatus.Up + : OperStatus.Down); if (0 != iface.linkSpeed) { - builder.setSpeed(InterfaceUtils.vppInterfaceSpeedToYang(iface.linkSpeed)); + builder.setSpeed(vppInterfaceSpeedToYang(iface.linkSpeed)); } if (iface.l2AddressLength == 6) { - builder.setPhysAddress(new PhysAddress(InterfaceUtils.vppPhysAddrToYang(iface.l2Address))); + builder.setPhysAddress(new PhysAddress(vppPhysAddrToYang(iface.l2Address))); } LOG.trace("Base attributes read for interface: {} as: {}", ifaceName, builder); } - @Nonnull - @SuppressWarnings("unchecked") - public static Map getCachedInterfaceDump(@Nonnull final ModificationCache ctx) { - return ctx.get(DUMPED_IFCS_CONTEXT_KEY) == null - ? new HashMap<>() - // allow customizers to update the cache - : (Map) ctx.get(DUMPED_IFCS_CONTEXT_KEY); - } - @Nonnull @Override public List getAllIds(@Nonnull final InstanceIdentifier id, @@ -141,9 +145,9 @@ public class InterfaceCustomizer extends FutureJVppCustomizer request.nameFilterValid = 0; final CompletableFuture swInterfaceDetailsReplyDumpCompletableFuture = - getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); + getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); final SwInterfaceDetailsReplyDump ifaces = - TranslateUtils.getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); + getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); if (null == ifaces || null == ifaces.swInterfaceDetails) { LOG.debug("No interfaces for :{} found in VPP", id); @@ -152,7 +156,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); final MappingContext mappingCtx = context.getMappingContext(); final Set interfacesIdxs = ifaces.swInterfaceDetails.stream() @@ -164,7 +168,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer .map((elt) -> { // Store interface name from VPP in context if not yet present if (!interfaceNamingContext.containsName(elt.swIfIndex, mappingCtx)) { - interfaceNamingContext.addName(elt.swIfIndex, TranslateUtils.toString(elt.interfaceName), + interfaceNamingContext.addName(elt.swIfIndex, toString(elt.interfaceName), mappingCtx); } LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP", @@ -199,10 +203,6 @@ public class InterfaceCustomizer extends FutureJVppCustomizer } } - private static boolean isRegularInterface(final SwInterfaceDetails iface) { - return iface.subId == 0; - } - @Override public void merge(@Nonnull final org.opendaylight.yangtools.concepts.Builder builder, @Nonnull final List readData) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceDataTranslator.java new file mode 100644 index 000000000..986b92c24 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/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.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.v3po.util.ByteDataTranslator; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; +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.rev150105.GreTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.SwInterfaceDetails; +import org.openvpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; +import org.openvpp.jvpp.core.dto.SwInterfaceDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; +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; + try { + 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); + } + } catch (VppBaseCallException e) { + callerLogger.warn("getVppInterfaceDetails for id :{} and name :{} failed with exception :", id, name, e); + throw new ReadFailedException(id, e); + } + + // 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; + } + + 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/InterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceUtils.java deleted file mode 100644 index 499f21dea..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceUtils.java +++ /dev/null @@ -1,289 +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.v3po.util.TranslateUtils; -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.rev150105.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.GreTunnel; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.jvpp.VppBaseCallException; -import org.openvpp.jvpp.core.dto.SwInterfaceDetails; -import org.openvpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; -import org.openvpp.jvpp.core.dto.SwInterfaceDump; -import org.openvpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class InterfaceUtils { - private static final Logger LOG = LoggerFactory.getLogger(InterfaceUtils.class); - - private static final Gauge64 vppLinkSpeed0 = new Gauge64(BigInteger.ZERO); - private static final Gauge64 vppLinkSpeed1 = new Gauge64(BigInteger.valueOf(10L * 1000000)); - private static final Gauge64 vppLinkSpeed2 = new Gauge64(BigInteger.valueOf(100L * 1000000)); - private static final Gauge64 vppLinkSpeed4 = new Gauge64(BigInteger.valueOf(1000L * 1000000)); - private static final Gauge64 vppLinkSpeed8 = new Gauge64(BigInteger.valueOf(10000L * 1000000)); - private static final Gauge64 vppLinkSpeed16 = new Gauge64(BigInteger.valueOf(40000L * 1000000)); - private static final Gauge64 vppLinkSpeed32 = new Gauge64(BigInteger.valueOf(100000L * 1000000)); - - private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); - - private static final int PHYSICAL_ADDRESS_LENGTH = 6; - - private static final Collector SINGLE_ITEM_COLLECTOR = - RWUtils.singleItemCollector(); - - private InterfaceUtils() { - throw new UnsupportedOperationException("This utility class cannot be instantiated"); - } - - /** - * 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 - */ - public static 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; - } - } - - private static final 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 - */ - public static String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) { - return vppPhysAddrToYang(vppPhysAddress, 0); - } - - public static 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); - } - - public static String printHexBinary(@Nonnull final byte[] bytes) { - Objects.requireNonNull(bytes, "bytes array should not be null"); - return printHexBinary(bytes, 0, bytes.length); - } - - private static 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 - */ - public static 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 - */ - public static 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 - public static SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final InstanceIdentifier id, - @Nonnull final String name, final int index, - @Nonnull final ModificationCache ctx) - 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; - try { - CompletionStage requestFuture = futureJVppCore.swInterfaceDump(request); - ifaces = TranslateUtils.getReplyForRead(requestFuture.toCompletableFuture(), id); - if (null == ifaces || null == ifaces.swInterfaceDetails || ifaces.swInterfaceDetails.isEmpty()) { - request.nameFilterValid = 0; - - LOG.warn("VPP returned null instead of interface by key {} and its not cached", name); - LOG.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 = TranslateUtils.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); - } - } catch (VppBaseCallException e) { - LOG.warn("getVppInterfaceDetails for id :{} and name :{} failed with exception :", id, name, e); - throw new ReadFailedException(id, e); - } - - // 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 - public static 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; - } - - return EthernetCsmacd.class; - } - - /** - * Check interface type. Uses interface details from VPP to determine. Uses {@link - * #getVppInterfaceDetails(FutureJVppCore, InstanceIdentifier, String, int, ModificationCache)} internally so tries to - * utilize cache before asking VPP. - */ - static boolean isInterfaceOfType(@Nonnull final FutureJVppCore jvpp, - @Nonnull final ModificationCache cache, - @Nonnull final InstanceIdentifier id, - final int index, - @Nonnull final Class ifcType) throws ReadFailedException { - final String name = id.firstKeyOf(Interface.class).getName(); - final SwInterfaceDetails vppInterfaceDetails = - getVppInterfaceDetails(jvpp, id, name, index, cache); - - return isInterfaceOfType(ifcType, vppInterfaceDetails); - } - - static boolean isInterfaceOfType(final Class ifcType, - final SwInterfaceDetails cachedDetails) { - return ifcType.equals(getInterfaceType(TranslateUtils.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 index e8e50f6d6..1590746c7 100644 --- 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 @@ -21,6 +21,7 @@ import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.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.rev150105.VppInterfaceStateAugmentationBuilder; @@ -33,10 +34,6 @@ import org.openvpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; - -import static com.google.common.base.Preconditions.checkState; - /** * Customizer for reading ietf-interfaces:interfaces-state/interface/iface_name/v3po:l2 */ 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 index 6ecaee63f..f84a3f792 100644 --- 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 @@ -56,7 +56,7 @@ import org.slf4j.LoggerFactory; * Customizer for reading vlan tag-rewrite configuration state form the VPP. */ public class RewriteCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer { + implements ReaderCustomizer, InterfaceDataTranslator { private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class); private final NamingContext interfaceContext; @@ -86,8 +86,8 @@ public class RewriteCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, - interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache()); + 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"); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceAclCustomizer.java index cbc8c7ed1..8e7568d85 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceAclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/SubInterfaceAclCustomizer.java @@ -21,11 +21,11 @@ import static com.google.common.base.Preconditions.checkNotNull; import static io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils.getSubInterfaceName; import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; @@ -49,7 +49,7 @@ import org.slf4j.LoggerFactory; * Customizer for reading ACLs enabled on given sub-interface. */ public class SubInterfaceAclCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer, AclReader { + implements ReaderCustomizer, AclReader, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class); private final NamingContext interfaceContext; @@ -82,13 +82,13 @@ public class SubInterfaceAclCustomizer extends FutureJVppCustomizer final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); checkArgument(subInterfacekey != null, "No sub-interface key found"); final String subInterfaceName = - getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); final ClassifyTableByInterface request = new ClassifyTableByInterface(); request.swIfIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); try { - final ClassifyTableByInterfaceReply reply = TranslateUtils - .getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id); + 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())); 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 index 167ae6a8c..3ba102fde 100644 --- 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 @@ -17,16 +17,15 @@ package io.fd.honeycomb.translate.v3po.interfacesstate; import static com.google.common.base.Preconditions.checkState; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.byteToBoolean; 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.ListReaderCustomizer; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -72,11 +71,12 @@ import org.slf4j.LoggerFactory; * Customizer for reading sub interfaces form the VPP. */ public class SubInterfaceCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer { + implements ListReaderCustomizer, ByteDataTranslator, + InterfaceDataTranslator { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class); - private NamingContext interfaceContext; 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) { @@ -84,6 +84,28 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer 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, @@ -105,7 +127,7 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer final CompletableFuture swInterfaceDetailsReplyDumpCompletableFuture = getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); final SwInterfaceDetailsReplyDump ifaces = - TranslateUtils.getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); + getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); if (null == ifaces || null == ifaces.swInterfaceDetails) { LOG.warn("Looking for sub-interfaces, but no interfaces found in VPP"); @@ -113,8 +135,9 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer } // 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))); + 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) @@ -126,7 +149,7 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer LOG.debug("Sub-interfaces of {} found in VPP: {}", ifaceName, interfacesKeys); return interfacesKeys; } catch (VppBaseCallException e) { - throw new ReadFailedException(id,e); + throw new ReadFailedException(id, e); } } @@ -149,8 +172,8 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, - interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache()); + 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"); @@ -169,20 +192,15 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer builder.setOperStatus(1 == iface.linkUpDown ? SubInterfaceStatus.Up : SubInterfaceStatus.Down); - builder.setIfIndex(InterfaceUtils.vppIfIndexToYang(iface.swIfIndex)); + builder.setIfIndex(vppIfIndexToYang(iface.swIfIndex)); if (iface.l2AddressLength == 6) { - builder.setPhysAddress(new PhysAddress(InterfaceUtils.vppPhysAddrToYang(iface.l2Address))); + builder.setPhysAddress(new PhysAddress(vppPhysAddrToYang(iface.l2Address))); } if (0 != iface.linkSpeed) { - builder.setSpeed(InterfaceUtils.vppInterfaceSpeedToYang(iface.linkSpeed)); + builder.setSpeed(vppInterfaceSpeedToYang(iface.linkSpeed)); } } - private static String getSubInterfaceName(final InstanceIdentifier id) { - return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), - Math.toIntExact(id.firstKeyOf(id.getTargetType()).getIdentifier())); - } - private Tags readTags(final SwInterfaceDetails iface) { final TagsBuilder tags = new TagsBuilder(); final List list = new ArrayList<>(); @@ -205,23 +223,6 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer return tags.build(); } - 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)); - } - private Match readMatch(final SwInterfaceDetails iface) { final MatchBuilder match = new MatchBuilder(); if (iface.subDefault == 1) { 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 index debf0efee..37d85abca 100644 --- 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 @@ -19,8 +19,8 @@ package io.fd.honeycomb.translate.v3po.interfacesstate; import static io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils.getSubInterfaceName; import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import javax.annotation.Nonnull; 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 index 5bf3435ce..37ba6bbd9 100644 --- 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 @@ -16,14 +16,12 @@ package io.fd.honeycomb.translate.v3po.interfacesstate; -import static io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType; - 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.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.util.Collections; import java.util.List; import java.util.Map; @@ -48,7 +46,7 @@ import org.slf4j.LoggerFactory; public class TapCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer { + implements ReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class); public static final String DUMPED_TAPS_CONTEXT_KEY = TapCustomizer.class.getName() + "dumpedTapsDuringGetAllIds"; @@ -78,7 +76,7 @@ public class TapCustomizer extends FutureJVppCustomizer final InterfaceKey key = id.firstKeyOf(Interface.class); final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class)) { + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class, LOG)) { return; } @@ -86,23 +84,23 @@ public class TapCustomizer extends FutureJVppCustomizer @SuppressWarnings("unchecked") Map mappedTaps = - (Map) ctx.getModificationCache().get(DUMPED_TAPS_CONTEXT_KEY); + (Map) ctx.getModificationCache().get(DUMPED_TAPS_CONTEXT_KEY); - if(mappedTaps == null) { + 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); + getFutureJVpp().swInterfaceTapDump(request); final SwInterfaceTapDetailsReplyDump reply = - TranslateUtils.getReplyForRead(swInterfaceTapDetailsReplyDumpCompletionStage.toCompletableFuture(), id); + getReplyForRead(swInterfaceTapDetailsReplyDumpCompletionStage.toCompletableFuture(), id); - if(null == reply || null == reply.swInterfaceTapDetails) { + 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)); + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); } ctx.getModificationCache().put(DUMPED_TAPS_CONTEXT_KEY, mappedTaps); @@ -111,7 +109,7 @@ public class TapCustomizer extends FutureJVppCustomizer final SwInterfaceTapDetails swInterfaceTapDetails = mappedTaps.get(index); LOG.trace("Tap interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceTapDetails); - builder.setTapName(TranslateUtils.toString(swInterfaceTapDetails.devName)); + builder.setTapName(toString(swInterfaceTapDetails.devName)); LOG.debug("Tap interface: {}, id: {} attributes read as: {}", key.getName(), index, builder); } catch (VppBaseCallException e) { LOG.warn("Failed to readCurrentAttributes for: {}", id, e); 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 index 96ae4fdf0..032b3c214 100644 --- 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 @@ -16,14 +16,12 @@ package io.fd.honeycomb.translate.v3po.interfacesstate; -import static io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType; - import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.math.BigInteger; import java.util.Collections; import java.util.List; @@ -50,10 +48,11 @@ import org.slf4j.LoggerFactory; public class VhostUserCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer { + implements ReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { + public static final String DUMPED_VHOST_USERS_CONTEXT_KEY = + VhostUserCustomizer.class.getName() + "dumpedVhostUsersDuringGetAllIds"; private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class); - public static final String DUMPED_VHOST_USERS_CONTEXT_KEY = VhostUserCustomizer.class.getName() + "dumpedVhostUsersDuringGetAllIds"; private NamingContext interfaceContext; public VhostUserCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { @@ -80,7 +79,8 @@ public class VhostUserCustomizer extends FutureJVppCustomizer final InterfaceKey key = id.firstKeyOf(Interface.class); final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class)) { + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class, + LOG)) { return; } @@ -88,23 +88,26 @@ public class VhostUserCustomizer extends FutureJVppCustomizer @SuppressWarnings("unchecked") Map mappedVhostUsers = - (Map) ctx.getModificationCache().get(DUMPED_VHOST_USERS_CONTEXT_KEY); + (Map) ctx.getModificationCache() + .get(DUMPED_VHOST_USERS_CONTEXT_KEY); - if(mappedVhostUsers == null) { + 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 CompletionStage + swInterfaceVhostUserDetailsReplyDumpCompletionStage = + getFutureJVpp().swInterfaceVhostUserDump(request); final SwInterfaceVhostUserDetailsReplyDump reply = - TranslateUtils.getReplyForRead(swInterfaceVhostUserDetailsReplyDumpCompletionStage.toCompletableFuture(), id); + getReplyForRead(swInterfaceVhostUserDetailsReplyDumpCompletionStage.toCompletableFuture(), id); - if(null == reply || null == reply.swInterfaceVhostUserDetails) { + if (null == reply || null == reply.swInterfaceVhostUserDetails) { mappedVhostUsers = Collections.emptyMap(); } else { - final List swInterfaceVhostUserDetails = reply.swInterfaceVhostUserDetails; + 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)); + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); } ctx.getModificationCache().put(DUMPED_VHOST_USERS_CONTEXT_KEY, mappedVhostUsers); @@ -112,12 +115,15 @@ public class VhostUserCustomizer extends FutureJVppCustomizer // 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); + LOG.trace("Vhost user interface: {} attributes returned from VPP: {}", key.getName(), + swInterfaceVhostUserDetails); - builder.setRole(swInterfaceVhostUserDetails.isServer == 1 ? VhostUserRole.Server : VhostUserRole.Client); + builder.setRole(swInterfaceVhostUserDetails.isServer == 1 + ? VhostUserRole.Server + : VhostUserRole.Client); builder.setFeatures(BigInteger.valueOf(swInterfaceVhostUserDetails.features)); builder.setNumMemoryRegions((long) swInterfaceVhostUserDetails.numRegions); - builder.setSocket(TranslateUtils.toString(swInterfaceVhostUserDetails.sockFilename)); + builder.setSocket(toString(swInterfaceVhostUserDetails.sockFilename)); builder.setVirtioNetHdrSize((long) swInterfaceVhostUserDetails.virtioNetHdrSz); builder.setConnectError(Integer.toString(swInterfaceVhostUserDetails.sockErrno)); 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 index b0a0496ce..2d01c3e39 100644 --- 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 @@ -17,14 +17,13 @@ package io.fd.honeycomb.translate.v3po.interfacesstate; import static com.google.common.base.Preconditions.checkState; -import static io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType; 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.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; @@ -52,7 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class VxlanCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer { + implements ReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class); private final NamingContext interfaceContext; @@ -81,7 +80,7 @@ public class VxlanCustomizer extends FutureJVppCustomizer try { 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)) { + if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanTunnel.class, LOG)) { return; } @@ -91,31 +90,32 @@ public class VxlanCustomizer extends FutureJVppCustomizer request.swIfIndex = index; final CompletionStage swInterfaceVxlanDetailsReplyDumpCompletionStage = - getFutureJVpp().vxlanTunnelDump(request); + getFutureJVpp().vxlanTunnelDump(request); final VxlanTunnelDetailsReplyDump reply = - TranslateUtils.getReplyForRead(swInterfaceVxlanDetailsReplyDumpCompletionStage.toCompletableFuture(), id); + 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); + "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()); + "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()); + new Ipv6Address(parseAddress(swInterfaceVxlanDetails.dstAddress).getHostAddress()); builder.setDst(new IpAddress(dstIpv6)); final Ipv6Address srcIpv6 = - new Ipv6Address(parseAddress(swInterfaceVxlanDetails.srcAddress).getHostAddress()); + new Ipv6Address(parseAddress(swInterfaceVxlanDetails.srcAddress).getHostAddress()); builder.setSrc(new IpAddress(srcIpv6)); } else { final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.dstAddress, 0, 4); @@ -126,11 +126,11 @@ public class VxlanCustomizer extends FutureJVppCustomizer builder.setSrc(new IpAddress(srcIpv4)); } builder.setEncapVrfId((long) swInterfaceVxlanDetails.encapVrfId); - builder.setVni( new VxlanVni((long) swInterfaceVxlanDetails.vni)); + builder.setVni(new VxlanVni((long) swInterfaceVxlanDetails.vni)); LOG.debug("Vxlan tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); } catch (VppBaseCallException e) { LOG.warn("Failed to readCurrentAttributes for: {}", id); - throw new ReadFailedException( id, e ); + throw new ReadFailedException(id, e); } } 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 index e6a9f85a2..deeba8ae0 100644 --- 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 @@ -17,14 +17,13 @@ package io.fd.honeycomb.translate.v3po.interfacesstate; import static com.google.common.base.Preconditions.checkState; -import static io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType; import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; @@ -53,7 +52,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class VxlanGpeCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer { + implements ReaderCustomizer, InterfaceDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class); private NamingContext interfaceContext; @@ -82,7 +81,7 @@ public class VxlanGpeCustomizer extends FutureJVppCustomizer try { 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)) { + if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanGpeTunnel.class, LOG)) { return; } @@ -92,31 +91,33 @@ public class VxlanGpeCustomizer extends FutureJVppCustomizer request.swIfIndex = index; final CompletionStage swInterfaceVxlanGpeDetailsReplyDumpCompletionStage = - getFutureJVpp().vxlanGpeTunnelDump(request); + getFutureJVpp().vxlanGpeTunnelDump(request); final VxlanGpeTunnelDetailsReplyDump reply = - TranslateUtils.getReplyForRead(swInterfaceVxlanGpeDetailsReplyDumpCompletionStage.toCompletableFuture(), id); + 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); + "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()); + "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()); + new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.remote).getHostAddress()); builder.setRemote(new IpAddress(remote6)); final Ipv6Address local6 = - new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.local).getHostAddress()); + new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.local).getHostAddress()); builder.setLocal(new IpAddress(local6)); } else { final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.remote, 0, 4); @@ -127,13 +128,13 @@ public class VxlanGpeCustomizer extends FutureJVppCustomizer builder.setLocal(new IpAddress(local4)); } builder.setVni(new VxlanGpeVni((long) swInterfaceVxlanGpeDetails.vni)); - builder.setNextProtocol(VxlanGpeNextProtocol.forValue(swInterfaceVxlanGpeDetails.protocol)); + 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); } catch (VppBaseCallException e) { LOG.warn("Failed to readCurrentAttributes for: {}", id); - throw new ReadFailedException( id, e ); + throw new ReadFailedException(id, e); } } 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 index f3605ca0f..e2df8e2cb 100644 --- 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 @@ -17,17 +17,18 @@ package io.fd.honeycomb.translate.v3po.interfacesstate.ip; import static com.google.common.base.Preconditions.checkNotNull; -import static io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv4ReadUtils.dumpAddresses; -import static io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv4ReadUtils.findIpAddressDetailsByIp; -import static io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv4ReadUtils.getAllIpv4AddressIds; import com.google.common.base.Optional; 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.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.exceptions.execution.DumpExecutionFailedException; +import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.AddressDumpExecutor; +import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.check.AddressDumpCheck; +import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.params.AddressDumpParams; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; 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; @@ -49,15 +50,22 @@ import org.slf4j.LoggerFactory; * Read customizer for interface Ipv4 addresses. */ public class Ipv4AddressCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer { + implements ListReaderCustomizer, 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) { + 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(new AddressDumpExecutor(futureJVppCore)) + .withNonEmptyPredicate(new AddressDumpCheck()) + .build(); } @Override @@ -69,38 +77,55 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer @Override public void readCurrentAttributes(@Nonnull InstanceIdentifier

id, @Nonnull AddressBuilder builder, @Nonnull ReadContext ctx) - throws ReadFailedException { + 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 = - dumpAddresses(getFutureJVpp(), id, interfaceName, interfaceIndex, ctx); + final Optional dumpOptional; + try { + dumpOptional = + dumpManager.getDump(CACHE_KEY, ctx.getModificationCache(), + new AddressDumpParams(interfaceIndex, false)); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } - final Optional ipAddressDetails = - findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); + if (dumpOptional.isPresent()) { + final Optional ipAddressDetails = + findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); - if (ipAddressDetails.isPresent()) { - final IpAddressDetails detail = ipAddressDetails.get(); - builder.setIp(TranslateUtils.arrayToIpv4AddressNoZone(detail.ip)) - .setSubnet(new PrefixLengthBuilder().setPrefixLength(Short.valueOf(detail.prefixLength)).build()); + 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()); + 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 { + 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 = - dumpAddresses(getFutureJVpp(), id, interfaceName, interfaceIndex, ctx); + final Optional dumpOptional; + try { + dumpOptional = + dumpManager.getDump(CACHE_KEY, ctx.getModificationCache(), + new AddressDumpParams(interfaceIndex, false)); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } return getAllIpv4AddressIds(dumpOptional, AddressKey::new); } 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 index 05b5ef47c..d95557e6d 100644 --- 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 @@ -17,9 +17,9 @@ 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.v3po.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.read.ReadFailedException; 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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4ReadUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4ReadUtils.java deleted file mode 100644 index c3c5616c9..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4ReadUtils.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.interfacesstate.ip; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.ModificationCache; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.v3po.util.ReadTimeoutException; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; -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 org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.jvpp.VppBaseCallException; -import org.openvpp.jvpp.core.dto.IpAddressDetails; -import org.openvpp.jvpp.core.dto.IpAddressDetailsReplyDump; -import org.openvpp.jvpp.core.dto.IpAddressDump; -import org.openvpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class providing Ipv4 read support. - */ -final class Ipv4ReadUtils { - - static final String CACHE_KEY = Ipv4ReadUtils.class.getName(); - private static final Logger LOG = LoggerFactory.getLogger(Ipv4ReadUtils.class); - - private Ipv4ReadUtils() { - throw new UnsupportedOperationException("This utility class cannot be instantiated"); - } - - // Many VPP APIs do not provide get operation for single item. Dump requests for all items are used instead. - // To improve HC performance, caching dump requests is a common pattern. - // TODO: HONEYCOMB-102 use more generic caching implementation, once provided - static Optional dumpAddresses(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final InstanceIdentifier id, - @Nonnull final String interfaceName, - final int interfaceIndex, @Nonnull final ReadContext ctx) - throws ReadFailedException { - - final String cacheKey = CACHE_KEY + interfaceName; - Optional dumpFromCache = dumpAddressFromCache(cacheKey, ctx.getModificationCache()); - - if (dumpFromCache.isPresent()) { - return dumpFromCache; - } - - Optional dumpFromOperational; - try { - dumpFromOperational = dumpAddressFromOperationalData(futureJVppCore, id, interfaceIndex); - } catch (VppBaseCallException e) { - throw new ReadFailedException(id, e); - } - - if (dumpFromOperational.isPresent()) { - ctx.getModificationCache().put(cacheKey, dumpFromOperational.get()); - } - - return dumpFromOperational; - } - - private static Optional dumpAddressFromCache(@Nonnull final String cacheKey, - @Nonnull final ModificationCache cache) { - LOG.debug("Retrieving Ipv4 addresses from cache for {}", cacheKey); - return Optional.fromNullable((IpAddressDetailsReplyDump) cache.get(cacheKey)); - } - - private static Optional dumpAddressFromOperationalData( - @Nonnull final FutureJVppCore futureJVppCore, @Nonnull final InstanceIdentifier id, final int interfaceIndex) - throws VppBaseCallException, ReadTimeoutException { - LOG.debug("Dumping Ipv4 addresses for interface id={}", interfaceIndex); - final IpAddressDump dumpRequest = new IpAddressDump(); - dumpRequest.isIpv6 = 0; - dumpRequest.swIfIndex = interfaceIndex; - return Optional.fromNullable( - TranslateUtils.getReplyForRead(futureJVppCore.ipAddressDump(dumpRequest).toCompletableFuture(), id)); - } - - @Nonnull static 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(TranslateUtils.arrayToIpv4AddressNoZone(detail.ip))) - .collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - } - - static 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(TranslateUtils.arrayToIpv4AddressNoZone(singleDetail.ip))) - .collect(RWUtils.singleItemCollector())); - } - return Optional.absent(); - } - -} 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 new file mode 100644 index 000000000..60447d974 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4Reader.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.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.v3po.util.Ipv4Translator; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; +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 org.openvpp.jvpp.core.dto.IpAddressDetails; +import org.openvpp.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(); + } + +} 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 index e1f306140..bd96bfbb9 100644 --- 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 @@ -17,18 +17,19 @@ package io.fd.honeycomb.translate.v3po.interfacesstate.ip; import static com.google.common.base.Preconditions.checkNotNull; -import static io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv4ReadUtils.dumpAddresses; -import static io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv4ReadUtils.findIpAddressDetailsByIp; -import static io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv4ReadUtils.getAllIpv4AddressIds; import com.google.common.base.Optional; 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.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.exceptions.execution.DumpExecutionFailedException; +import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.AddressDumpExecutor; +import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.check.AddressDumpCheck; +import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.params.AddressDumpParams; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; 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; @@ -51,16 +52,22 @@ import org.slf4j.LoggerFactory; * Read customizer for sub-interface Ipv4 addresses. */ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer { + implements ListReaderCustomizer, Ipv4Reader { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class); + private static final String CACHE_KEY = SubInterfaceIpv4AddressCustomizer.class.getName(); 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(new AddressDumpExecutor(futureJVppCore)) + .withNonEmptyPredicate(new AddressDumpCheck()) + .build(); } @Override @@ -72,38 +79,49 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer @Override public void readCurrentAttributes(@Nonnull InstanceIdentifier
id, @Nonnull AddressBuilder builder, @Nonnull ReadContext ctx) - throws ReadFailedException { + 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 = - dumpAddresses(getFutureJVpp(), id, subInterfaceName, subInterfaceIndex, ctx); + final Optional dumpOptional; + try { + dumpOptional = dumpManager + .getDump(CACHE_KEY, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + final Optional ipAddressDetails = - findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); + findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); if (ipAddressDetails.isPresent()) { final IpAddressDetails detail = ipAddressDetails.get(); - builder.setIp(TranslateUtils.arrayToIpv4AddressNoZone(detail.ip)) - .setSubnet(new PrefixLengthBuilder().setPrefixLength(Short.valueOf(detail.prefixLength)).build()); + builder.setIp(arrayToIpv4AddressNoZone(detail.ip)) + .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()); + subInterfaceName, subInterfaceIndex, id, builder.build()); } } } @Override public List getAllIds(@Nonnull InstanceIdentifier
id, @Nonnull ReadContext ctx) - throws ReadFailedException { + 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 = - dumpAddresses(getFutureJVpp(), id, subInterfaceName, subInterfaceIndex, ctx); + final Optional dumpOptional; + try { + dumpOptional = dumpManager + .getDump(CACHE_KEY, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } return getAllIpv4AddressIds(dumpOptional, AddressKey::new); } @@ -115,6 +133,6 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer private static String getSubInterfaceName(@Nonnull final InstanceIdentifier
id) { return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), - Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier())); + Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier())); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/AddressDumpExecutor.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/AddressDumpExecutor.java new file mode 100644 index 000000000..a94e47c91 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/AddressDumpExecutor.java @@ -0,0 +1,47 @@ +package io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump; + + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.honeycomb.translate.util.read.cache.exceptions.execution.DumpExecutionFailedException; +import io.fd.honeycomb.translate.util.read.cache.exceptions.execution.i.DumpCallFailedException; +import io.fd.honeycomb.translate.util.read.cache.exceptions.execution.i.DumpTimeoutException; +import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.params.AddressDumpParams; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import org.openvpp.jvpp.core.dto.IpAddressDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; + +public class AddressDumpExecutor + implements EntityDumpExecutor, ByteDataTranslator, + JvppReplyConsumer { + + private FutureJVppCore vppApi; + + public AddressDumpExecutor(@Nonnull final FutureJVppCore vppApi) { + this.vppApi = checkNotNull(vppApi, "Vpp api refference cannot be null"); + } + + @Override + public IpAddressDetailsReplyDump executeDump(final AddressDumpParams params) throws DumpExecutionFailedException { + checkNotNull(params, "Address dump params cannot be null"); + + IpAddressDump dumpRequest = new IpAddressDump(); + dumpRequest.isIpv6 = booleanToByte(params.isIpv6()); + dumpRequest.swIfIndex = params.getInterfaceIndex(); + + try { + return getReply(vppApi.ipAddressDump(dumpRequest).toCompletableFuture()); + } catch (TimeoutException e) { + throw DumpTimeoutException + .wrapTimeoutException("Dumping or addresses ended in timeout[params : ]" + params, e); + } catch (VppBaseCallException e) { + throw DumpCallFailedException.wrapFailedCallException("Dumping of addresses failed[params : ]" + params, e); + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/check/AddressDumpCheck.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/check/AddressDumpCheck.java new file mode 100644 index 000000000..d6ab28db0 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/check/AddressDumpCheck.java @@ -0,0 +1,16 @@ +package io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.check; + +import io.fd.honeycomb.translate.util.read.cache.EntityDumpNonEmptyCheck; +import io.fd.honeycomb.translate.util.read.cache.exceptions.check.DumpCheckFailedException; +import io.fd.honeycomb.translate.util.read.cache.exceptions.check.i.DumpEmptyException; +import org.openvpp.jvpp.core.dto.IpAddressDetailsReplyDump; + +public class AddressDumpCheck implements EntityDumpNonEmptyCheck { + + @Override + public void assertNotEmpty(final IpAddressDetailsReplyDump data) throws DumpCheckFailedException { + if (data == null || data.ipAddressDetails == null) { + throw new DumpEmptyException("Invalid data dumped"); + } + } +} 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 new file mode 100644 index 000000000..9b7591b58 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java @@ -0,0 +1,28 @@ +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/notification/InterfaceChangeNotificationProducer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/notification/InterfaceChangeNotificationProducer.java index 481a2eac9..974c4f876 100644 --- 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 @@ -13,6 +13,7 @@ * 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; @@ -22,8 +23,8 @@ 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.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.CompletionStage; @@ -51,7 +52,7 @@ import org.slf4j.LoggerFactory; * received notification, it transforms it into its BA equivalent and pushes into HC's notification collector. */ @NotThreadSafe -public final class InterfaceChangeNotificationProducer implements ManagedNotificationProducer { +public final class InterfaceChangeNotificationProducer implements ManagedNotificationProducer, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(InterfaceChangeNotificationProducer.class); @@ -76,11 +77,11 @@ public final class InterfaceChangeNotificationProducer implements ManagedNotific 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)); - } + swInterfaceSetFlagsNotification -> { + LOG.trace("Interface notification received: {}", swInterfaceSetFlagsNotification); + // TODO HONEYCOMB-166 this should be lazy + collector.onNotification(transformNotification(swInterfaceSetFlagsNotification)); + } ); } @@ -89,10 +90,14 @@ public final class InterfaceChangeNotificationProducer implements ManagedNotific 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(); + .setName(getIfcName(swInterfaceSetFlagsNotification)) + .setAdminStatus(swInterfaceSetFlagsNotification.adminUpDown == 1 + ? InterfaceStatus.Up + : InterfaceStatus.Down) + .setOperStatus(swInterfaceSetFlagsNotification.linkUpDown == 1 + ? InterfaceStatus.Up + : InterfaceStatus.Down) + .build(); } } @@ -107,8 +112,8 @@ public final class InterfaceChangeNotificationProducer implements ManagedNotific final Optional optionalName = interfaceContext.getNameIfPresent(swInterfaceSetFlagsNotification.swIfIndex, mappingContext); return optionalName.isPresent() - ? new InterfaceNameOrIndex(optionalName.get()) - : new InterfaceNameOrIndex((long) swInterfaceSetFlagsNotification.swIfIndex); + ? new InterfaceNameOrIndex(optionalName.get()) + : new InterfaceNameOrIndex((long) swInterfaceSetFlagsNotification.swIfIndex); } @Override @@ -132,9 +137,11 @@ public final class InterfaceChangeNotificationProducer implements ManagedNotific final CompletionStage wantInterfaceEventsReplyCompletionStage; try { wantInterfaceEventsReplyCompletionStage = jvpp.wantInterfaceEvents(wantInterfaceEvents); - TranslateUtils.getReply(wantInterfaceEventsReplyCompletionStage.toCompletableFuture()); + getReply(wantInterfaceEventsReplyCompletionStage.toCompletableFuture()); } catch (VppBaseCallException | TimeoutException e) { - LOG.warn("Unable to {} interface notifications", enableDisable == 1 ? "enable" : "disable", e); + LOG.warn("Unable to {} interface notifications", enableDisable == 1 + ? "enable" + : "disable", e); throw new IllegalStateException("Unable to control interface notifications", e); } } 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 index 92eb396a8..4042dfac8 100644 --- 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 @@ -16,13 +16,13 @@ package io.fd.honeycomb.translate.v3po.vpp; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte; - import com.google.common.base.Preconditions; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.AddressTranslator; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; @@ -46,7 +46,8 @@ import org.slf4j.LoggerFactory; * VPP.
Equivalent of invoking {@code vppctl set bridge-domain arp term} command. */ public class ArpTerminationTableEntryCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer { + implements ListWriterCustomizer, ByteDataTranslator, + AddressTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(ArpTerminationTableEntryCustomizer.class); @@ -62,7 +63,7 @@ public class ArpTerminationTableEntryCustomizer extends FutureJVppCustomizer public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final ArpTerminationTableEntry dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { try { LOG.debug("Creating ARP termination table entry: {} {}", id, dataAfter); bdIpMacAddDel(id, dataAfter, writeContext, true); @@ -79,14 +80,14 @@ public class ArpTerminationTableEntryCustomizer extends FutureJVppCustomizer @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."); + "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 { + throws WriteFailedException { try { LOG.debug("Deleting ARP termination table entry entry: {} {}", id, dataBefore); bdIpMacAddDel(id, dataBefore, writeContext, false); @@ -100,23 +101,23 @@ public class ArpTerminationTableEntryCustomizer extends FutureJVppCustomizer private void bdIpMacAddDel(@Nonnull final InstanceIdentifier id, @Nonnull final ArpTerminationTableEntry entry, final WriteContext writeContext, boolean isAdd) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { 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); + getFutureJVpp().bdIpMacAddDel(request); - TranslateUtils.getReplyForWrite(replyCompletionStage.toCompletableFuture(), id); + 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 = TranslateUtils.parseMac(entry.getPhysAddress().getValue()); + request.macAddress = parseMac(entry.getPhysAddress().getValue()); final IpAddress ipAddress = entry.getIpAddress(); if (ipAddress.getIpv6Address() != null) { @@ -124,7 +125,7 @@ public class ArpTerminationTableEntryCustomizer extends FutureJVppCustomizer throw new UnsupportedOperationException("IPv6 address for ARP termination table is not supported yet"); } - request.ipAddress = TranslateUtils.ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(ipAddress.getIpv4Address())); + 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 index 83be3c62c..45d0e6460 100644 --- 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 @@ -18,13 +18,13 @@ package io.fd.honeycomb.translate.v3po.vpp; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte; import com.google.common.base.Preconditions; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; @@ -41,8 +41,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BridgeDomainCustomizer - extends FutureJVppCustomizer - implements ListWriterCustomizer { + extends FutureJVppCustomizer + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); @@ -51,14 +51,15 @@ public class BridgeDomainCustomizer @GuardedBy("this") private int bridgeDomainIndexCounter = 1; - public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull 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"); } private BridgeDomainAddDelReply addOrUpdateBridgeDomain(@Nonnull final InstanceIdentifier id, final int bdId, @Nonnull final BridgeDomain bd) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { final BridgeDomainAddDelReply reply; final BridgeDomainAddDel request = new BridgeDomainAddDel(); request.bdId = bdId; @@ -69,7 +70,7 @@ public class BridgeDomainCustomizer request.arpTerm = booleanToByte(bd.isArpTermination()); request.isAdd = ADD_OR_UPDATE_BD; - reply = TranslateUtils.getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); + reply = getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId); return reply; } @@ -78,7 +79,7 @@ public class BridgeDomainCustomizer public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final BridgeDomain dataBefore, @Nonnull final WriteContext ctx) - throws WriteFailedException { + throws WriteFailedException { LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx); final String bdName = dataBefore.getName(); @@ -113,7 +114,7 @@ public class BridgeDomainCustomizer public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final BridgeDomain dataBefore, @Nonnull final WriteContext ctx) - throws WriteFailedException { + 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()); @@ -122,7 +123,7 @@ public class BridgeDomainCustomizer final BridgeDomainAddDel request = new BridgeDomainAddDel(); request.bdId = bdId; - TranslateUtils.getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); + getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId); } catch (VppBaseCallException e) { LOG.warn("Bridge domain {} (id={}) delete failed", bdName, bdId); @@ -134,13 +135,13 @@ public class BridgeDomainCustomizer public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter, @Nonnull final WriteContext ctx) - throws WriteFailedException { + throws WriteFailedException { LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter, - ctx); + ctx); final String bdName = checkNotNull(dataAfter.getName()); checkArgument(bdName.equals(dataBefore.getName()), - "BridgeDomain name changed. It should be deleted and then created."); + "BridgeDomain name changed. It should be deleted and then created."); try { 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 index d72d95493..29b4b939f 100644 --- 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 @@ -16,15 +16,14 @@ package io.fd.honeycomb.translate.v3po.vpp; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.parseMac; - 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.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.v3po.util.MacTranslator; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; @@ -47,7 +46,8 @@ import org.slf4j.LoggerFactory; * VPP.
Equivalent of invoking {@code vppctl l2fib add/del} command. */ public class L2FibEntryCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer { + implements ListWriterCustomizer, ByteDataTranslator, MacTranslator, + JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); @@ -64,7 +64,7 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer @Override public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2FibEntry dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + throws WriteFailedException { try { LOG.debug("Creating L2 FIB entry: {} {}", id, dataAfter); l2FibAddDel(id, dataAfter, writeContext, true); @@ -80,13 +80,13 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer @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."); + "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 { + throws WriteFailedException { try { LOG.debug("Deleting L2 FIB entry: {} {}", id, dataBefore); l2FibAddDel(id, dataBefore, writeContext, false); @@ -99,7 +99,7 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer private void l2FibAddDel(@Nonnull final InstanceIdentifier id, @Nonnull final L2FibEntry entry, final WriteContext writeContext, boolean isAdd) - throws VppBaseCallException, WriteTimeoutException { + throws VppBaseCallException, WriteTimeoutException { final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); final int bdId = bdContext.getIndex(bdName, writeContext.getMappingContext()); @@ -112,9 +112,9 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer final L2FibAddDel l2FibRequest = createL2FibRequest(entry, bdId, swIfIndex, isAdd); LOG.debug("Sending l2FibAddDel request: {}", l2FibRequest); final CompletionStage l2FibAddDelReplyCompletionStage = - getFutureJVpp().l2FibAddDel(l2FibRequest); + getFutureJVpp().l2FibAddDel(l2FibRequest); - TranslateUtils.getReplyForWrite(l2FibAddDelReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(l2FibAddDelReplyCompletionStage.toCompletableFuture(), id); } private L2FibAddDel createL2FibRequest(final L2FibEntry entry, final int bdId, final int swIfIndex, boolean isAdd) { @@ -132,9 +132,9 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer // 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 static long macToLong(final String macAddress) { + 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); + 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 index 558e6ba41..62f69d646 100644 --- 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 @@ -19,7 +19,6 @@ 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 static io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceUtils.printHexBinary; import com.google.common.base.Optional; import com.google.common.primitives.UnsignedInts; @@ -27,8 +26,9 @@ 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.v3po.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -61,7 +61,8 @@ import org.slf4j.LoggerFactory; * class table verbose} command. */ public class ClassifySessionReader extends FutureJVppCustomizer - implements ListReaderCustomizer, VppNodeReader { + implements ListReaderCustomizer, + InterfaceDataTranslator, VppNodeReader, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionReader.class); static final String CACHE_KEY = ClassifySessionReader.class.getName(); @@ -89,7 +90,7 @@ public class ClassifySessionReader extends FutureJVppCustomizer @Override public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final ClassifySessionBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { + throws ReadFailedException { LOG.debug("Reading attributes for classify session: {}", id); final ClassifySessionKey key = id.firstKeyOf(ClassifySession.class); @@ -98,12 +99,13 @@ public class ClassifySessionReader extends FutureJVppCustomizer final ClassifySessionDetailsReplyDump classifySessionDump = dumpClassifySessions(id, ctx); final byte[] match = DatatypeConverter.parseHexBinary(key.getMatch().getValue().replace(":", "")); final Optional classifySession = - findClassifySessionDetailsByMatch(classifySessionDump, match); + findClassifySessionDetailsByMatch(classifySessionDump, match); if (classifySession.isPresent()) { final ClassifySessionDetails detail = classifySession.get(); builder.setHitNext( - readVppNode(detail.tableId, detail.hitNextIndex, classifyTableContext, ctx.getMappingContext(), LOG).get()); + 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())); @@ -133,14 +135,14 @@ public class ClassifySessionReader extends FutureJVppCustomizer @Nullable private ClassifySessionDetailsReplyDump dumpClassifySessions(@Nonnull final InstanceIdentifier id, @Nonnull final ReadContext ctx) - throws ReadFailedException { + 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); + (ClassifySessionDetailsReplyDump) ctx.getModificationCache().get(cacheKey); if (classifySessionDump != null) { LOG.debug("Classify sessions is present in cache: {}", cacheKey); return classifySessionDump; @@ -148,16 +150,16 @@ public class ClassifySessionReader extends FutureJVppCustomizer 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); + "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); try { final ClassifySessionDump dumpRequest = new ClassifySessionDump(); dumpRequest.tableId = tableId; - classifySessionDump = TranslateUtils - .getReplyForRead(getFutureJVpp().classifySessionDump(dumpRequest).toCompletableFuture(), id); + classifySessionDump = + getReplyForRead(getFutureJVpp().classifySessionDump(dumpRequest).toCompletableFuture(), id); if (classifySessionDump != null) { // update the cache: @@ -171,19 +173,19 @@ public class ClassifySessionReader extends FutureJVppCustomizer } private static Optional findClassifySessionDetailsByMatch( - @Nullable final ClassifySessionDetailsReplyDump classifySessionDump, @Nonnull final byte[] match) { + @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()); + .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())); + "Found %d classify sessions witch given match. Single session expected.", + filteredSessions.size())); } } return Optional.absent(); @@ -198,8 +200,8 @@ public class ClassifySessionReader extends FutureJVppCustomizer 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()); + .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 index d2029a368..e4870aecf 100644 --- 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 @@ -19,12 +19,12 @@ 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 static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte; 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.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import java.util.concurrent.CompletionStage; @@ -49,7 +49,7 @@ import org.slf4j.LoggerFactory; * to VPP.
Equivalent to invoking {@code vppctl classify table} command. */ public class ClassifySessionWriter extends VppNodeWriter - implements ListWriterCustomizer { + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(ClassifySessionWriter.class); private final VppClassifierContextManager classifyTableContext; @@ -97,32 +97,32 @@ public class ClassifySessionWriter extends VppNodeWriter private void classifyAddDelSession(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final ClassifySession classifySession, @Nonnull final WriteContext writeContext) - throws VppBaseCallException, WriteFailedException { + 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); + "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); + getClassifyTable(writeContext, id.firstIdentifierOf(ClassifyTable.class), isAdd); final int hitNextIndex = getNodeIndex(classifySession.getHitNext(), classifyTable, classifyTableContext, - writeContext.getMappingContext(), id); + writeContext.getMappingContext(), id); final int opaqueIndex = - getOpaqueIndex(classifySession.getOpaqueIndex(), classifyTable, writeContext.getMappingContext(), id); + getOpaqueIndex(classifySession.getOpaqueIndex(), classifyTable, writeContext.getMappingContext(), id); final CompletionStage createClassifyTableReplyCompletionStage = getFutureJVpp() - .classifyAddDelSession( - getClassifyAddDelSessionRequest(isAdd, classifySession, tableIndex, hitNextIndex, opaqueIndex)); + .classifyAddDelSession( + getClassifyAddDelSessionRequest(isAdd, classifySession, tableIndex, hitNextIndex, opaqueIndex)); - TranslateUtils.getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); } private ClassifyTable getClassifyTable(final WriteContext writeContext, - @Nonnull final InstanceIdentifier id, - final boolean isAdd) { + @Nonnull final InstanceIdentifier id, + final boolean isAdd) { final Optional classifyTable; if (isAdd) { classifyTable = writeContext.readAfter(id); @@ -132,11 +132,11 @@ public class ClassifySessionWriter extends VppNodeWriter return classifyTable.get(); } - private static ClassifyAddDelSession getClassifyAddDelSessionRequest(final boolean isAdd, - @Nonnull final ClassifySession classifySession, - final int tableIndex, - final int hitNextIndex, - final int opaqueIndex) { + 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; @@ -152,7 +152,7 @@ public class ClassifySessionWriter extends VppNodeWriter private int getOpaqueIndex(@Nullable final OpaqueIndex opaqueIndex, final ClassifyTable classifyTable, final MappingContext ctx, final InstanceIdentifier id) - throws VppBaseCallException, WriteFailedException { + throws VppBaseCallException, WriteFailedException { if (opaqueIndex == null) { return ~0; // value not specified } 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 index ad238d8bb..70af10eb7 100644 --- 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 @@ -18,15 +18,16 @@ 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 io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceUtils.printHexBinary; 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.ListReaderCustomizer; +import io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.v3po.util.MacTranslator; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -55,7 +56,9 @@ import org.slf4j.LoggerFactory; * class table} command. */ public class ClassifyTableReader extends FutureJVppCustomizer - implements ListReaderCustomizer, VppNodeReader { + implements ListReaderCustomizer, VppNodeReader, + MacTranslator, + InterfaceDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableReader.class); private final VppClassifierContextManager classifyTableContext; @@ -82,7 +85,7 @@ public class ClassifyTableReader extends FutureJVppCustomizer @Override public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final ClassifyTableBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { + throws ReadFailedException { LOG.debug("Reading attributes for classify table: {}", id); final ClassifyTableKey key = id.firstKeyOf(ClassifyTable.class); @@ -98,7 +101,7 @@ public class ClassifyTableReader extends FutureJVppCustomizer try { final ClassifyTableInfoReply reply = - TranslateUtils.getReplyForRead(getFutureJVpp().classifyTableInfo(request).toCompletableFuture(), id); + getReplyForRead(getFutureJVpp().classifyTableInfo(request).toCompletableFuture(), id); // mandatory values: builder.setName(tableName); @@ -108,14 +111,14 @@ public class ClassifyTableReader extends FutureJVppCustomizer // optional value read from context final Optional tableBaseNode = - classifyTableContext.getTableBaseNode(tableName, ctx.getMappingContext()); + 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()); + readVppNode(reply.tableId, reply.missNextIndex, classifyTableContext, ctx.getMappingContext(), LOG) + .get()); builder.setMask(new HexString(printHexBinary(reply.mask))); builder.setActiveSessions(UnsignedInts.toLong(reply.activeSessions)); @@ -138,8 +141,9 @@ public class ClassifyTableReader extends FutureJVppCustomizer @Nonnull final ReadContext context) throws ReadFailedException { LOG.debug("Reading list of keys for classify tables: {}", id); try { - final ClassifyTableIdsReply classifyTableIdsReply = TranslateUtils - .getReplyForRead(getFutureJVpp().classifyTableIds(new ClassifyTableIds()).toCompletableFuture(), 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()); 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 index 3dc3cf7d1..6f4959c23 100644 --- 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 @@ -19,11 +19,11 @@ 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 static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte; import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import java.util.concurrent.CompletionStage; @@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory; * VPP.
Equivalent to invoking {@code vppctl classify table} command. */ public class ClassifyTableWriter extends VppNodeWriter - implements ListWriterCustomizer { + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableWriter.class); private final VppClassifierContextManager classifyTableContext; @@ -58,14 +58,16 @@ public class ClassifyTableWriter extends VppNodeWriter @Override public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final ClassifyTable dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { + 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()); + 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()); + 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); @@ -86,7 +88,7 @@ public class ClassifyTableWriter extends VppNodeWriter 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); + "Removing classify table {}, but index could not be found in the classify table context", tableName); final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); try { @@ -102,17 +104,17 @@ public class ClassifyTableWriter extends VppNodeWriter private int classifyAddDelTable(final boolean isAdd, @Nonnull final InstanceIdentifier id, @Nonnull final ClassifyTable table, final int tableId, final MappingContext ctx) - throws VppBaseCallException, WriteFailedException { + throws VppBaseCallException, WriteFailedException { final int missNextIndex = - getNodeIndex(table.getMissNext(), table, classifyTableContext, ctx, id); + getNodeIndex(table.getMissNext(), table, classifyTableContext, ctx, id); final CompletionStage createClassifyTableReplyCompletionStage = - getFutureJVpp() - .classifyAddDelTable(getClassifyAddDelTableRequest(isAdd, tableId, table, missNextIndex, ctx)); + getFutureJVpp() + .classifyAddDelTable(getClassifyAddDelTableRequest(isAdd, tableId, table, missNextIndex, ctx)); final ClassifyAddDelTableReply reply = - TranslateUtils.getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); + getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); return reply.newTableIndex; } 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 index a4667bf4d..abc49cccb 100644 --- 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 @@ -20,8 +20,8 @@ import static com.google.common.base.Preconditions.checkArgument; import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import io.fd.honeycomb.translate.v3po.util.ReadTimeoutException; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.write.WriteFailedException; import java.util.concurrent.CompletionStage; import javax.annotation.Nonnull; @@ -33,7 +33,7 @@ import org.openvpp.jvpp.core.dto.GetNextIndex; import org.openvpp.jvpp.core.dto.GetNextIndexReply; import org.openvpp.jvpp.core.future.FutureJVppCore; -abstract class VppNodeWriter extends FutureJVppCustomizer { +abstract class VppNodeWriter extends FutureJVppCustomizer implements JvppReplyConsumer { protected VppNodeWriter(@Nonnull final FutureJVppCore futureJvpp) { super(futureJvpp); @@ -42,35 +42,37 @@ abstract class VppNodeWriter extends FutureJVppCustomizer { 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 { + throws VppBaseCallException, WriteFailedException { if (node.getPacketHandlingAction() != null) { return node.getPacketHandlingAction().getIntValue(); } else { - return nodeNameToIndex(classifyTable, node.getVppNodeName().getValue(), vppClassifierContextManager, ctx, id); + 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 VppBaseCallException, WriteFailedException { - checkArgument(classifyTable != null && classifyTable.getClassifierNode() != null, "to use relative node names, table classifier node needs to be provided"); + throws VppBaseCallException, 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); + getFutureJVpp().getNextIndex(request); final GetNextIndexReply reply; try { - reply = TranslateUtils.getReplyForRead(getNextIndexCompletionStage.toCompletableFuture(), id); + 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 (ReadTimeoutException e) { throw new WriteFailedException(id, String.format("Failed to get node index for %s relative to %s", - nextNodeName, classifyTable.getClassifierNode()), e); + 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 index d254a7912..fcf0ff16a 100644 --- 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 @@ -16,13 +16,12 @@ package io.fd.honeycomb.translate.v3po.vppstate; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.byteToBoolean; - 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.ListReaderCustomizer; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.v3po.util.NamingContext; import java.util.ArrayList; @@ -44,12 +43,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class BridgeDomainCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer { + implements ListReaderCustomizer, ByteDataTranslator { private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); private final NamingContext bdContext; - public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull 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"); } @@ -57,9 +57,9 @@ public final class BridgeDomainCustomizer extends FutureJVppCustomizer @Override public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final BridgeDomainBuilder builder, @Nonnull final ReadContext context) - throws ReadFailedException { + throws ReadFailedException { LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: id={}, builderbuilder={}, context={}", - id, builder, context); + id, builder, context); final BridgeDomainKey key = id.firstKeyOf(id.getTargetType()); LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: key={}", key); 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 index 2de19a1c1..e03b95f1a 100644 --- 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 @@ -16,19 +16,17 @@ package io.fd.honeycomb.translate.v3po.vppstate; -import static io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceUtils.vppPhysAddrToYang; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.byteToBoolean; - 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.ListReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceDataTranslator; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.v3po.util.ReadTimeoutException; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -56,12 +54,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class L2FibEntryCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer { + implements ListReaderCustomizer, ByteDataTranslator, + InterfaceDataTranslator { private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); private static final Collector SINGLE_ITEM_COLLECTOR = - RWUtils.singleItemCollector(); + RWUtils.singleItemCollector(); private final NamingContext bdContext; private final NamingContext interfaceContext; @@ -76,7 +75,7 @@ public final class L2FibEntryCustomizer extends FutureJVppCustomizer @Override public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final L2FibEntryBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { + throws ReadFailedException { final L2FibEntryKey key = id.firstKeyOf(id.getTargetType()); final BridgeDomainKey bridgeDomainKey = id.firstKeyOf(BridgeDomain.class); @@ -86,12 +85,12 @@ public final class L2FibEntryCustomizer extends FutureJVppCustomizer 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); + .equals(new PhysAddress(vppPhysAddrToYang(Longs.toByteArray(e.mac), 2)))) + .collect(SINGLE_ITEM_COLLECTOR); builder.setAction(byteToBoolean(entry.filterMac) - ? L2FibFilter.class - : L2FibForward.class); + ? L2FibFilter.class + : L2FibForward.class); builder.setBridgedVirtualInterface(byteToBoolean(entry.bviMac)); if (entry.swIfIndex != -1) { @@ -107,14 +106,14 @@ public final class L2FibEntryCustomizer extends FutureJVppCustomizer @Nonnull private List dumpL2Fibs(final InstanceIdentifier id, final int bdId) - throws VppBaseCallException, ReadTimeoutException { + throws VppBaseCallException, ReadTimeoutException { final L2FibTableDump l2FibRequest = new L2FibTableDump(); l2FibRequest.bdId = bdId; final CompletableFuture l2FibTableDumpCompletableFuture = - getFutureJVpp().l2FibTableDump(l2FibRequest).toCompletableFuture(); + getFutureJVpp().l2FibTableDump(l2FibRequest).toCompletableFuture(); - final L2FibTableEntryReplyDump dump = TranslateUtils.getReplyForRead(l2FibTableDumpCompletableFuture, id); + final L2FibTableEntryReplyDump dump = getReplyForRead(l2FibTableDumpCompletableFuture, id); if (null == dump || null == dump.l2FibTableEntry) { return Collections.emptyList(); 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 index eedf7642f..6c2b1833b 100644 --- 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 @@ -19,8 +19,9 @@ package io.fd.honeycomb.translate.v3po.vppstate; 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.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer; import java.util.concurrent.CompletionStage; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; @@ -35,8 +36,8 @@ import org.openvpp.jvpp.core.dto.ShowVersionReply; import org.openvpp.jvpp.core.future.FutureJVppCore; public final class VersionCustomizer - extends FutureJVppCustomizer - implements ReaderCustomizer { + extends FutureJVppCustomizer + implements ReaderCustomizer, ByteDataTranslator, JvppReplyConsumer { public VersionCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { super(futureJVppCore); @@ -59,12 +60,12 @@ public final class VersionCustomizer try { // Execute with timeout final CompletionStage showVersionFuture = getFutureJVpp().showVersion(new ShowVersion()); - final ShowVersionReply reply = TranslateUtils.getReplyForRead(showVersionFuture.toCompletableFuture(), id); + final ShowVersionReply reply = getReplyForRead(showVersionFuture.toCompletableFuture(), id); - builder.setBranch(TranslateUtils.toString(reply.version)); - builder.setName(TranslateUtils.toString(reply.program)); - builder.setBuildDate(TranslateUtils.toString(reply.buildDate)); - builder.setBuildDirectory(TranslateUtils.toString(reply.buildDirectory)); + builder.setBranch(toString(reply.version)); + builder.setName(toString(reply.program)); + builder.setBuildDate(toString(reply.buildDate)); + builder.setBuildDirectory(toString(reply.buildDirectory)); } catch (VppBaseCallException e) { throw new ReadFailedException(id, e); } 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 index 7381533e5..52a7a5c2d 100644 --- 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 @@ -16,6 +16,9 @@ package io.fd.honeycomb.translate.v3po; + + + import static org.hamcrest.CoreMatchers.hasItems; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; 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 index 0dabe1468..9ff5b1b2d 100644 --- 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 @@ -19,8 +19,8 @@ package io.fd.honeycomb.translate.v3po.interfaces; import static org.mockito.Mockito.doReturn; import com.google.common.base.Optional; -import io.fd.honeycomb.translate.write.WriteContext; 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; 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 index 0c1d2d72f..a47f5b641 100644 --- 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 @@ -30,8 +30,8 @@ import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import io.fd.honeycomb.translate.v3po.test.ContextTestUtils; +import io.fd.honeycomb.translate.v3po.util.Ipv4Translator; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; import org.junit.Test; @@ -53,30 +53,30 @@ import org.openvpp.jvpp.core.dto.DeleteVhostUserIfReply; import org.openvpp.jvpp.core.dto.ModifyVhostUserIf; import org.openvpp.jvpp.core.dto.ModifyVhostUserIfReply; -public class VhostUserCustomizerTest extends WriterCustomizerTest { +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); + 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.rev150105.VhostUser.class); + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class); customizer = new VhostUserCustomizer(api, new NamingContext("generatedInterfaceName", "test-instance")); } private CreateVhostUserIf verifyCreateVhostUserIfWasInvoked(final VhostUser vhostUser) - throws VppInvocationException { + throws VppInvocationException { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CreateVhostUserIf.class); verify(api).createVhostUserIf(argumentCaptor.capture()); final CreateVhostUserIf actual = argumentCaptor.getValue(); assertEquals(0, actual.customDevInstance); - assertEquals(TranslateUtils.booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer); + assertEquals(booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer); assertEquals(0, actual.renumber); assertEquals(0, actual.useCustomMac); assertArrayEquals(vhostUser.getSocket().getBytes(), actual.sockFilename); @@ -85,13 +85,13 @@ public class VhostUserCustomizerTest extends WriterCustomizerTest { } private ModifyVhostUserIf verifyModifyVhostUserIfWasInvoked(final VhostUser vhostUser, final int swIfIndex) - throws VppInvocationException { + throws VppInvocationException { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(ModifyVhostUserIf.class); verify(api).modifyVhostUserIf(argumentCaptor.capture()); final ModifyVhostUserIf actual = argumentCaptor.getValue(); assertEquals(0, actual.customDevInstance); - assertEquals(TranslateUtils.booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer); + assertEquals(booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer); assertEquals(0, actual.renumber); assertEquals(swIfIndex, actual.swIfIndex); assertArrayEquals(vhostUser.getSocket().getBytes(), actual.sockFilename); @@ -122,7 +122,7 @@ public class VhostUserCustomizerTest extends WriterCustomizerTest { customizer.writeCurrentAttributes(ID, vhostUser, writeContext); verifyCreateVhostUserIfWasInvoked(vhostUser); verify(mappingContext).put(eq(ContextTestUtils.getMappingIid(IFACE_NAME, "test-instance")), eq( - ContextTestUtils.getMapping(IFACE_NAME, 0).get())); + ContextTestUtils.getMapping(IFACE_NAME, 0).get())); } @Test 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 index 745276473..416468300 100644 --- 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 @@ -24,8 +24,8 @@ import static org.mockito.Mockito.when; import com.google.common.io.BaseEncoding; import io.fd.honeycomb.translate.v3po.test.ContextTestUtils; +import io.fd.honeycomb.translate.v3po.util.Ipv4Translator; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; import org.junit.Before; @@ -45,7 +45,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.openvpp.jvpp.core.dto.IpNeighborAddDel; import org.openvpp.jvpp.core.dto.IpNeighborAddDelReply; -public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest { +public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest implements Ipv4Translator { private static final String IFC_CTX_NAME = "ifc-test-instance"; private static final String IFACE_NAME = "parent"; @@ -85,7 +85,7 @@ public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest { assertEquals(0, request.isIpv6); assertEquals(1, request.isAdd); assertEquals(1, request.isStatic); - assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.dstAddress).getValue()); + assertEquals("1.2.168.192", arrayToIpv4AddressNoZone(request.dstAddress).getValue()); assertEquals("aabbccee1122", BaseEncoding.base16().lowerCase().encode(request.macAddress)); assertEquals(5, request.swIfIndex); } @@ -111,7 +111,7 @@ public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest { assertEquals(0, request.isIpv6); assertEquals(0, request.isAdd); assertEquals(1, request.isStatic); - assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.dstAddress).getValue()); + assertEquals("1.2.168.192", arrayToIpv4AddressNoZone(request.dstAddress).getValue()); assertEquals("aabbccee1122", BaseEncoding.base16().lowerCase().encode(request.macAddress)); assertEquals(5, request.swIfIndex); } 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 index acc407bd3..5c6f88abd 100644 --- 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 @@ -49,7 +49,7 @@ import org.openvpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; import org.openvpp.jvpp.core.dto.SwInterfaceDump; public class InterfaceCustomizerTest extends - ListReaderCustomizerTest { + ListReaderCustomizerTest implements InterfaceDataTranslator { private static final String IFC_CTX_NAME = "ifc-test-instance"; private static final String IFACE0_NAME = "eth0"; @@ -96,23 +96,23 @@ public class InterfaceCustomizerTest extends private void verifySwInterfaceDumpWasInvoked(final int nameFilterValid, final String ifaceName, final int dumpIfcsInvocationCount) - throws VppInvocationException { + throws VppInvocationException { final SwInterfaceDump expected = new SwInterfaceDump(); - expected.nameFilterValid = (byte)nameFilterValid; + expected.nameFilterValid = (byte) nameFilterValid; expected.nameFilter = ifaceName.getBytes(); verify(api, times(dumpIfcsInvocationCount)).swInterfaceDump(expected); } - private static void assertIfacesAreEqual(final Interface iface, final SwInterfaceDetails details) { + private void assertIfacesAreEqual(final Interface iface, final SwInterfaceDetails details) { assertEquals(iface.getName(), new String(details.interfaceName)); - Assert.assertEquals(InterfaceUtils.yangIfIndexToVpp(iface.getIfIndex().intValue()), details.swIfIndex); - assertEquals(iface.getPhysAddress().getValue(), InterfaceUtils.vppPhysAddrToYang(details.l2Address)); + 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)); + .child(Interface.class, new InterfaceKey(IFACE0_NAME)); final InterfaceBuilder builder = getCustomizer().getBuilder(id); final SwInterfaceDetails iface = new SwInterfaceDetails(); @@ -134,7 +134,7 @@ public class InterfaceCustomizerTest extends public void testReadCurrentAttributesFailed() throws Exception { final String ifaceName = IFACE0_NAME; final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(ifaceName)); + .child(Interface.class, new InterfaceKey(ifaceName)); final InterfaceBuilder builder = getCustomizer().getBuilder(id); whenSwInterfaceDumpThenReturn(Collections.emptyList()); @@ -152,7 +152,7 @@ public class InterfaceCustomizerTest extends @Test public void testReadSubInterface() throws Exception { final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(SUB_IFACE_NAME)); + .child(Interface.class, new InterfaceKey(SUB_IFACE_NAME)); final InterfaceBuilder builder = mock(InterfaceBuilder.class); final SwInterfaceDetails iface = new SwInterfaceDetails(); @@ -172,7 +172,7 @@ public class InterfaceCustomizerTest extends @Test public void testGetAllIds() throws Exception { final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class); + .child(Interface.class); final SwInterfaceDetails swIf0 = new SwInterfaceDetails(); swIf0.swIfIndex = 0; @@ -188,7 +188,7 @@ public class InterfaceCustomizerTest extends whenSwInterfaceDumpThenReturn(Arrays.asList(swIf0, swIf1, swSubIf1)); final List expectedIds = Arrays.asList(new InterfaceKey(IFACE0_NAME), new InterfaceKey( - IFACE1_NAME)); + IFACE1_NAME)); final List actualIds = getCustomizer().getAllIds(id, ctx); verifySwInterfaceDumpWasInvoked(0, "", 1); @@ -200,7 +200,7 @@ public class InterfaceCustomizerTest extends @Test public void testGetAllIdsWithDisabled() throws Exception { final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class); + .child(Interface.class); doReturn(true).when(interfaceDisableContext).isInterfaceDisabled(1, mappingContext); 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 new file mode 100644 index 000000000..56567f282 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/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.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.rev150105.Tap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.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/InterfaceUtilsTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceUtilsTest.java deleted file mode 100644 index c74e1ccfb..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/InterfaceUtilsTest.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.rev150105.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel; - -public class InterfaceUtilsTest { - - @Test - public void testVppPhysAddrToYang() throws Exception { - assertEquals("01:02:03:04:05:06", InterfaceUtils.vppPhysAddrToYang(new byte[]{1, 2, 3, 4, 5, 6})); - assertEquals("0a:0b:0c:0d:0e:0f", InterfaceUtils.vppPhysAddrToYang(new byte[]{0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0})); - } - - @Test(expected = NullPointerException.class) - public void testVppPhysAddrToYangFailNullArgument() throws Exception { - InterfaceUtils.vppPhysAddrToYang(null); - } - - @Test(expected = IllegalArgumentException.class) - public void testVppPhysAddrToYangInvalidByteArrayLength() throws Exception { - InterfaceUtils.vppPhysAddrToYang(new byte[]{1, 2, 3, 4, 5}); - } - - @Test - public void testGetInterfaceType() { - assertEquals(Tap.class, InterfaceUtils.getInterfaceType("tap0")); - assertEquals(VxlanTunnel.class, InterfaceUtils.getInterfaceType("vxlan0")); - assertEquals(VxlanGpeTunnel.class, InterfaceUtils.getInterfaceType("vxlan_gpe0")); - assertEquals(VhostUser.class, InterfaceUtils.getInterfaceType("VirtualEthernet0/0/0")); - assertEquals(EthernetCsmacd.class, InterfaceUtils.getInterfaceType("eth0.0")); - assertEquals(EthernetCsmacd.class, InterfaceUtils.getInterfaceType("local0")); - } -} \ 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 index be0ef14df..d351d2402 100644 --- 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 @@ -16,12 +16,11 @@ package io.fd.honeycomb.translate.v3po.interfacesstate.ip; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.reverseBytes; -import static org.hamcrest.CoreMatchers.is; + +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableList; @@ -29,13 +28,14 @@ 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.translate.v3po.test.ContextTestUtils; +import io.fd.honeycomb.translate.v3po.util.Ipv4Translator; import io.fd.honeycomb.translate.v3po.util.NamingContext; -import io.fd.honeycomb.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; import java.util.Arrays; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; -import org.hamcrest.CoreMatchers; +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; @@ -54,13 +54,15 @@ import org.openvpp.jvpp.core.dto.IpAddressDetails; import org.openvpp.jvpp.core.dto.IpAddressDetailsReplyDump; import org.openvpp.jvpp.core.dto.IpAddressDump; -public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest { +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"; + public static final String CACHE_KEY = Ipv4AddressCustomizer.class.getName(); private NamingContext interfacesContext; @@ -89,64 +91,45 @@ public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest id = getId("192.168.2.1", IFACE_NAME); - - getCustomizer().readCurrentAttributes(id, builder, ctx); - - assertEquals("192.168.2.1", builder.getIp().getValue()); - } - @Test public void testReadCurrentAttributesFor2Ifcs() throws ReadFailedException { - ModificationCache cache = new ModificationCache(); + //changed to mock to not store first dumped data(otherwise that double thenReturn on line 118 is not gonna work) + ModificationCache cache = mock(ModificationCache.class); IpAddressDetails detail1 = new IpAddressDetails(); IpAddressDetails detail2 = new IpAddressDetails(); detail1.ip = reverseBytes( - TranslateUtils.ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); detail2.ip = reverseBytes( - TranslateUtils.ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.2")))); + 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); - when(api.ipAddressDump(Mockito.any(IpAddressDump.class))).thenReturn(future(reply)).thenReturn(future(reply2)); + 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, CoreMatchers.hasItem(new AddressKey(new Ipv4AddressNoZone("192.168.2.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, CoreMatchers.hasItem(new AddressKey(new Ipv4AddressNoZone("192.168.2.2")))); + assertThat(ifc2Ids, Matchers.hasItem(new AddressKey(new Ipv4AddressNoZone("192.168.2.2")))); AddressBuilder builder = new AddressBuilder(); getCustomizer().readCurrentAttributes(id, builder, ctx); @@ -157,7 +140,7 @@ public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest id = getId("192.168.2.1", IFACE_NAME); - - List ids = getCustomizer().getAllIds(id, ctx).stream() - .map(key -> key.getIp()) - .collect(Collectors.toList()); - - verify(api, times(0)).ipAddressDump(Mockito.any(IpAddressDump.class)); - 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 testGetAllIdsFromOperationalData() throws ReadFailedException { + public void testGetAllIdsFromSuccessfull() throws ReadFailedException { ModificationCache cache = new ModificationCache(); IpAddressDetails detail1 = new IpAddressDetails(); @@ -227,11 +176,11 @@ public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest id = getId("192.168.2.1", IFACE_NAME); List ids = getCustomizer().getAllIds(id, ctx).stream() - .map(key -> key.getIp()) - .collect(Collectors.toList()); + .map(key -> key.getIp()) + .collect(Collectors.toList()); assertEquals(3, ids.size()); assertEquals(true, "192.168.2.1".equals(ids.get(0).getValue())); 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 index 6029f3faf..f41448bf0 100644 --- 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 @@ -16,7 +16,6 @@ package io.fd.honeycomb.translate.v3po.vpp; -import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doReturn; @@ -25,6 +24,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.fd.honeycomb.translate.v3po.test.ContextTestUtils; +import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator; import io.fd.honeycomb.translate.v3po.util.NamingContext; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; @@ -40,7 +40,7 @@ import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.core.dto.BridgeDomainAddDel; import org.openvpp.jvpp.core.dto.BridgeDomainAddDelReply; -public class BridgeDomainCustomizerTest extends WriterCustomizerTest { +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; @@ -53,7 +53,7 @@ public class BridgeDomainCustomizerTest extends WriterCustomizerTest { @Nullable private static Boolean intToBoolean(final int value) { - if (value == 0) { + if (value == 0) { return Boolean.FALSE; } if (value == 1) { @@ -63,7 +63,7 @@ public class BridgeDomainCustomizerTest extends WriterCustomizerTest { } private static KeyedInstanceIdentifier bdIdentifierForName( - final String bdName) { + final String bdName) { return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(bdName)); } @@ -79,17 +79,17 @@ public class BridgeDomainCustomizerTest extends WriterCustomizerTest { 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(); + .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 { + throws VppInvocationException { final BridgeDomainAddDel expected = new BridgeDomainAddDel(); expected.arpTerm = booleanToByte(bd.isArpTermination()); expected.flood = booleanToByte(bd.isFlood()); @@ -128,7 +128,7 @@ public class BridgeDomainCustomizerTest extends WriterCustomizerTest { verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId); verify(mappingContext).put( - ContextTestUtils.getMappingIid(bdName, BD_CTX_NAME), ContextTestUtils.getMapping(bdName, bdId).get()); + ContextTestUtils.getMappingIid(bdName, BD_CTX_NAME), ContextTestUtils.getMapping(bdName, bdId).get()); } @Test @@ -144,7 +144,7 @@ public class BridgeDomainCustomizerTest extends WriterCustomizerTest { verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId); verify(mappingContext).put( - ContextTestUtils.getMappingIid(bdName, BD_CTX_NAME), ContextTestUtils.getMapping(bdName, bdId).get()); + ContextTestUtils.getMappingIid(bdName, BD_CTX_NAME), ContextTestUtils.getMapping(bdName, bdId).get()); } @Test @@ -226,16 +226,16 @@ public class BridgeDomainCustomizerTest extends WriterCustomizerTest { final byte uufBefore = 0; final BridgeDomain dataBefore = - generateBridgeDomain(bdName, arpTermBefore, floodBefore, forwardBefore, learnBefore, uufBefore); + generateBridgeDomain(bdName, arpTermBefore, floodBefore, forwardBefore, learnBefore, uufBefore); final BridgeDomain dataAfter = - generateBridgeDomain(bdName, arpTermBefore ^ 1, floodBefore ^ 1, forwardBefore ^ 1, learnBefore ^ 1, - uufBefore ^ 1); + generateBridgeDomain(bdName, arpTermBefore ^ 1, floodBefore ^ 1, forwardBefore ^ 1, learnBefore ^ 1, + uufBefore ^ 1); whenBridgeDomainAddDelThenSuccess(); customizer - .updateCurrentAttributes(bdIdentifierForName(bdName), dataBefore, dataAfter, - writeContext); + .updateCurrentAttributes(bdIdentifierForName(bdName), dataBefore, dataAfter, + writeContext); verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter, bdId); } @@ -248,8 +248,8 @@ public class BridgeDomainCustomizerTest extends WriterCustomizerTest { try { customizer - .updateCurrentAttributes(bdIdentifierForName(bdName), bdBefore, bdAfter, - writeContext); + .updateCurrentAttributes(bdIdentifierForName(bdName), bdBefore, bdAfter, + writeContext); } catch (IllegalArgumentException e) { verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class)); return; @@ -269,8 +269,8 @@ public class BridgeDomainCustomizerTest extends WriterCustomizerTest { try { customizer - .updateCurrentAttributes(bdIdentifierForName(bdName), bdBefore, bdAfter, - writeContext); + .updateCurrentAttributes(bdIdentifierForName(bdName), bdBefore, bdAfter, + writeContext); } catch (WriteFailedException.UpdateFailedException e) { verifyBridgeDomainAddOrUpdateWasInvoked(bdAfter, bdId); return; 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 index 728ba9306..174e27215 100644 --- 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 @@ -62,14 +62,14 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest { ContextTestUtils.mockMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME); customizer = new L2FibEntryCustomizer( - api, - new NamingContext("generatedBdName", BD_CTX_NAME), - new NamingContext("generatedIfaceName", IFC_CTX_NAME)); + 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)); + .child(L2FibTable.class).child(L2FibEntry.class, new L2FibEntryKey(address)); } private void whenL2FibAddDelThenSuccess() { @@ -105,7 +105,7 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest { } private void verifyL2FibAddDelWasInvoked(final L2FibAddDel expected) throws - VppInvocationException { + VppInvocationException { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(L2FibAddDel.class); verify(api).l2FibAddDel(argumentCaptor.capture()); final L2FibAddDel actual = argumentCaptor.getValue(); @@ -153,7 +153,7 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest { @Test(expected = UnsupportedOperationException.class) public void testUpdate() throws Exception { customizer.updateCurrentAttributes(InstanceIdentifier.create(L2FibEntry.class), mock(L2FibEntry.class), - mock(L2FibEntry.class), writeContext); + mock(L2FibEntry.class), writeContext); } @Test -- cgit 1.2.3-korg