summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Gradzki <mgradzki@cisco.com>2016-05-16 14:51:53 +0200
committerMarek Gradzki <mgradzki@cisco.com>2016-05-18 08:02:33 +0200
commitc068b27764b2d8f3f4a0023da12d93b8ebe0b176 (patch)
tree5ab8c70ceb96254b8375c6873e981db5563cdcf3
parent02b2183a113214039611373f84352da4a5f57e2c (diff)
Fix interface dump caching
Change-Id: I18d29bebf754c34bbc05e5c9cfb78d8aba87c205 Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java4
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java7
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java63
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtilsTest.java12
4 files changed, 54 insertions, 32 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
index eca13c1c9..74ea45c11 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
@@ -16,8 +16,6 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
-import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer.getCachedInterfaceDump;
-
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
@@ -70,7 +68,7 @@ public class EthernetCustomizer extends FutureJVppCustomizer
final InterfaceKey key = id.firstKeyOf(Interface.class);
final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
- interfaceContext.getIndex(key.getName()), getCachedInterfaceDump(ctx));
+ interfaceContext.getIndex(key.getName()), ctx);
builder.setMtu((int) iface.linkMtu);
switch (iface.linkDuplex) {
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java
index 82e114603..51d4022d7 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java
@@ -23,6 +23,7 @@ import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@@ -72,11 +73,9 @@ public class InterfaceCustomizer extends FutureJVppCustomizer
LOG.debug("Reading attributes for interface: {}", id);
final InterfaceKey key = id.firstKeyOf(id.getTargetType());
- final Map<Integer, SwInterfaceDetails> cachedDump = getCachedInterfaceDump(ctx);
-
// Pass cached details from getAllIds to getDetails to avoid additional dumps
final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
- interfaceContext.getIndex(key.getName()), cachedDump);
+ interfaceContext.getIndex(key.getName()), ctx);
LOG.debug("Interface details for interface: {}, details: {}", key.getName(), iface);
builder.setName(key.getName());
@@ -97,7 +96,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer
@SuppressWarnings("unchecked")
public static Map<Integer, SwInterfaceDetails> getCachedInterfaceDump(final @Nonnull Context ctx) {
return ctx.get(DUMPED_IFCS_CONTEXT_KEY) == null
- ? Collections.emptyMap()
+ ? new HashMap<>() // allow customizers to update the cache
: (Map<Integer, SwInterfaceDetails>) ctx.get(DUMPED_IFCS_CONTEXT_KEY);
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
index 036018e88..1ee472745 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
@@ -17,6 +17,7 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
import static com.google.common.base.Preconditions.checkNotNull;
+import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer.getCachedInterfaceDump;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
@@ -26,6 +27,7 @@ import java.math.BigInteger;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletionStage;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
@@ -92,15 +94,15 @@ public final class InterfaceUtils {
}
// TODO rename and move to V3poUtils
+
/**
- * Reads first 6 bytes of supplied byte array and converts to string as Yang dictates
- * <p> Replace later with
+ * Reads first 6 bytes of supplied byte array and converts to string as Yang dictates <p> 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 NullPointerException if vppPhysAddress is null
* @throws IllegalArgumentException if vppPhysAddress.length < 6
*/
public static String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) {
@@ -110,7 +112,7 @@ public final class InterfaceUtils {
StringBuilder physAddr = new StringBuilder();
appendHexByte(physAddr, vppPhysAddress[0]);
- for (int i=1; i < PHYSICAL_ADDRESS_LENGTH; i++) {
+ for (int i = 1; i < PHYSICAL_ADDRESS_LENGTH; i++) {
physAddr.append(":");
appendHexByte(physAddr, vppPhysAddress[i]);
}
@@ -144,34 +146,34 @@ public final class InterfaceUtils {
/**
* Queries VPP for interface description given interface key.
*
- * @param futureJvpp VPP Java Future API
- * @param key interface key
- * @param index VPP index of the interface
- * @param allInterfaces cached interfaces dump with all the interfaces. If interface not present, another dump all
- * will be performed
- *
+ * @param futureJvpp VPP Java Future API
+ * @param key interface key
+ * @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
*/
@Nonnull
public static SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVpp futureJvpp,
@Nonnull InterfaceKey key, final int index,
- @Nonnull final Map<Integer, SwInterfaceDetails> allInterfaces) {
+ @Nonnull final Context ctx) {
final SwInterfaceDump request = new SwInterfaceDump();
request.nameFilter = key.getName().getBytes();
request.nameFilterValid = 1;
+ final Map<Integer, SwInterfaceDetails> allInterfaces = getCachedInterfaceDump(ctx);
+
+ // Returned cached if available
+ if (allInterfaces.containsKey(index)) {
+ return allInterfaces.get(index);
+ }
+
CompletionStage<SwInterfaceDetailsReplyDump> requestFuture = futureJvpp.swInterfaceDump(request);
SwInterfaceDetailsReplyDump ifaces = V3poUtils.getReply(requestFuture.toCompletableFuture());
if (null == ifaces || null == ifaces.swInterfaceDetails || ifaces.swInterfaceDetails.isEmpty()) {
request.nameFilterValid = 0;
- // Returned cached if available
- if(allInterfaces.containsKey(index)) {
- return allInterfaces.get(index);
- }
-
LOG.warn("VPP returned null instead of interface by key {} and its not cached", key.getName());
LOG.warn("Iterating through all the interfaces to find interface: {}", key.getName());
@@ -179,10 +181,20 @@ public final class InterfaceUtils {
requestFuture = futureJvpp.swInterfaceDump(request);
ifaces = V3poUtils.getReply(requestFuture.toCompletableFuture());
- return ifaces.swInterfaceDetails.stream().filter((swIfc) -> swIfc.swIfIndex == index)
- .findFirst().orElseThrow(() -> new IllegalArgumentException("Unable to find interface " + key.getName()));
+ // 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 " + key.getName());
}
- return Iterables.getOnlyElement(ifaces.swInterfaceDetails);
+
+ final SwInterfaceDetails iface = Iterables.getOnlyElement(ifaces.swInterfaceDetails);
+ allInterfaces.put(index, iface); // update the cache
+ return iface;
}
/**
@@ -193,15 +205,15 @@ public final class InterfaceUtils {
*/
@Nonnull
public static Class<? extends InterfaceType> getInterfaceType(@Nonnull final String interfaceName) {
- if(interfaceName.startsWith("tap")) {
+ if (interfaceName.startsWith("tap")) {
return Tap.class;
}
- if(interfaceName.startsWith("vxlan")) {
+ if (interfaceName.startsWith("vxlan")) {
return VxlanTunnel.class;
}
- if(interfaceName.startsWith("VirtualEthernet")) {
+ if (interfaceName.startsWith("VirtualEthernet")) {
return VhostUser.class;
}
@@ -210,8 +222,9 @@ public final class InterfaceUtils {
static boolean isInterfaceOfType(final Context ctx, final int index,
final Class<? extends InterfaceType> ifcType) {
- final SwInterfaceDetails cachedDetails = checkNotNull(InterfaceCustomizer.getCachedInterfaceDump(ctx).get(index),
- "Interface {} cannot be found in context", index);
+ final SwInterfaceDetails cachedDetails =
+ checkNotNull(getCachedInterfaceDump(ctx).get(index),
+ "Interface {} cannot be found in context", index);
return ifcType.equals(getInterfaceType(V3poUtils.toString(cachedDetails.interfaceName)));
}
}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtilsTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtilsTest.java
index ff6ed3dde..0a0eff03b 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtilsTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtilsTest.java
@@ -19,6 +19,10 @@ package io.fd.honeycomb.v3po.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.VxlanTunnel;
public class InterfaceUtilsTest {
@@ -37,4 +41,12 @@ public class InterfaceUtilsTest {
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(VhostUser.class, InterfaceUtils.getInterfaceType("VirtualEthernet0/0/0"));
+ assertEquals(EthernetCsmacd.class, InterfaceUtils.getInterfaceType("local0"));
+ }
} \ No newline at end of file