HONEYCOMB-317 - L2 entry model updates 79/4279/2 v1.17.01-RC0
authorJan Srnicek <[email protected]>
Wed, 14 Dec 2016 14:26:13 +0000 (15:26 +0100)
committerMarek Gradzki <[email protected]>
Wed, 14 Dec 2016 21:00:07 +0000 (22:00 +0100)
Require either filter to be specified or outgoing-interface reference

Change-Id: Iec72348b04520cb3eb6717f970355bd0f52330f7
Signed-off-by: Jan Srnicek <[email protected]>
Signed-off-by: Marek Gradzki <[email protected]>
v3po/api/src/main/yang/v3po.yang
v3po/postman_rest_collection.json
v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java
v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizerTest.java

index 828a095..6333ec5 100644 (file)
@@ -227,12 +227,10 @@ module v3po {
         }
 
         leaf outgoing-interface {
-          type string;
-          // mandatory true;
-          // mandatory for forward action
-          // FIXME VPP's CLI does not require to set iface id for filter action
-          // VPP's binary api in constrast to CLI does some checks on the iface id value,
-          // so currently it has to be set for all actions
+          // either filter must be specified or interface(can't be both)
+          when "../action != 'l2-fib-filter'";
+          type if:interface-ref;
+          // mandatory true; - when is not actually resolved, so mandatory can't be in place
           description
             "One of interfaces assigned to the FIB table's bridge-domain.";
         }
index 2812508..ffbba01 100644 (file)
                        "description": "Adds L2 FIB static entry. Corresponds to invoking:\n\nvppctl l2fib add 00:01:02:03:04:05 [bd_id] filter\n\nTo verify run:\n\nvppctl show l2fib verbose",
                        "collectionId": "5bad4634-e5cf-900e-9733-0976aa9bea64",
                        "responses": [],
-                       "rawModeData": "{\n    \"l2-fib-entry\": [\n        {\n            \"phys-address\": \"00:01:02:03:04:05\",\n            \"outgoing-interface\": \"local0\",\n            \"static-config\": \"true\",\n            \"action\": \"l2-fib-filter\"\n        }\n    ]\n}",
+                       "rawModeData": "{\n    \"l2-fib-entry\": [\n        {\n            \"phys-address\": \"00:01:02:03:04:05\",\n \"static-config\": \"true\",\n            \"action\": \"l2-fib-filter\"\n        }\n    ]\n}",
                        "folder": "e742a44e-2e82-fe0c-d7c1-2f6b6bc1f0e9"
                },
                {
index 6328555..0eced82 100644 (file)
 
 package io.fd.hc2vpp.v3po.vpp;
 
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import com.google.common.primitives.Longs;
-import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
 import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
 import io.fd.hc2vpp.common.translate.util.MacTranslator;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.translate.write.WriteContext;
 import io.fd.honeycomb.translate.write.WriteFailedException;
 import io.fd.vpp.jvpp.core.dto.L2FibAddDel;
@@ -48,6 +51,7 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer
         JvppReplyConsumer {
 
     private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class);
+    public static final int NO_INTERFACE_REF = -1;
 
     private final NamingContext bdContext;
     private final NamingContext interfaceContext;
@@ -55,8 +59,8 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer
     public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext,
                                 @Nonnull final NamingContext interfaceContext) {
         super(futureJVppCore);
-        this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null");
-        this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
+        this.bdContext = checkNotNull(bdContext, "bdContext should not be null");
+        this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null");
     }
 
     @Override
@@ -90,15 +94,11 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer
     private void l2FibAddDel(@Nonnull final InstanceIdentifier<L2FibEntry> id, @Nonnull final L2FibEntry entry,
                              final WriteContext writeContext, boolean isAdd) throws WriteFailedException {
         final String bdName = id.firstKeyOf(BridgeDomain.class).getName();
-        final int bdId = bdContext.getIndex(bdName, writeContext.getMappingContext());
-
-        int swIfIndex = -1;
-        final String swIfName = entry.getOutgoingInterface();
-        if (swIfName != null) {
-            swIfIndex = interfaceContext.getIndex(swIfName, writeContext.getMappingContext());
-        }
+        final MappingContext mappingContext = writeContext.getMappingContext();
+        final int bdId = bdContext.getIndex(bdName, mappingContext);
 
-        final L2FibAddDel l2FibRequest = createL2FibRequest(entry, bdId, swIfIndex, isAdd);
+        final L2FibAddDel l2FibRequest = createL2FibRequest(entry, bdId, getCheckedInterfaceIndex(entry,
+                mappingContext), isAdd);
         LOG.debug("Sending l2FibAddDel request: {}", l2FibRequest);
         final CompletionStage<L2FibAddDelReply> l2FibAddDelReplyCompletionStage =
                 getFutureJVpp().l2FibAddDel(l2FibRequest);
@@ -106,6 +106,20 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer
         getReplyForWrite(l2FibAddDelReplyCompletionStage.toCompletableFuture(), id);
     }
 
+    private int getCheckedInterfaceIndex(final L2FibEntry entry, final MappingContext mappingContext) {
+        if (L2FibFilter.class == entry.getAction()) {
+            // if filter, interface should not be defined
+            checkArgument(entry.getOutgoingInterface() == null, "Interface reference should not be defined for type %s",
+                    L2FibFilter.class);
+            return NO_INTERFACE_REF;
+        } else {
+            // if type is not filter, interface reference is mandatory
+            return interfaceContext.getIndex(
+                    checkNotNull(entry.getOutgoingInterface(), "Interface reference should be defined for type %s",
+                            entry.getAction()), mappingContext);
+        }
+    }
+
     private L2FibAddDel createL2FibRequest(final L2FibEntry entry, final int bdId, final int swIfIndex, boolean isAdd) {
         final L2FibAddDel request = new L2FibAddDel();
         request.mac = macToLong(entry.getPhysAddress().getValue());
index 689d536..551b087 100644 (file)
@@ -35,6 +35,7 @@ import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibForward;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder;
@@ -52,6 +53,7 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest {
     private static final int BD_ID = 111;
     private static final String IFACE_NAME = "eth0";
     private static final int IFACE_ID = 123;
+    private static final int NO_INTERFACE = -1;
 
     private L2FibEntryCustomizer customizer;
 
@@ -79,11 +81,11 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest {
         doReturn(failedFuture()).when(api).l2FibAddDel(any(L2FibAddDel.class));
     }
 
-    private L2FibAddDel generateL2FibAddDelRequest(final long mac, final byte isAdd) {
+    private L2FibAddDel generateL2FibAddDelFilterRequest(final long mac, final byte isAdd, final int ifaceIndex) {
         final L2FibAddDel request = new L2FibAddDel();
         request.mac = mac;
         request.bdId = BD_ID;
-        request.swIfIndex = IFACE_ID;
+        request.swIfIndex = ifaceIndex;
         request.isAdd = isAdd;
         if (isAdd == 1) {
             request.staticMac = 1;
@@ -92,17 +94,41 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest {
         return request;
     }
 
-    private L2FibEntry generateL2FibEntry(final PhysAddress address) {
+    private L2FibAddDel generateL2FibAddDelForwardRequest(final long mac, final byte isAdd, final int ifaceIndex) {
+        final L2FibAddDel request = new L2FibAddDel();
+        request.mac = mac;
+        request.bdId = BD_ID;
+        request.swIfIndex = ifaceIndex;
+        request.isAdd = isAdd;
+        if (isAdd == 1) {
+            request.staticMac = 1;
+            request.filterMac = 0;
+        }
+        return request;
+    }
+
+    private L2FibEntry generateL2FibFilterEntry(final PhysAddress address) {
         final L2FibEntryBuilder entry = new L2FibEntryBuilder();
         entry.setKey(new L2FibEntryKey(address));
         entry.setPhysAddress(address);
         entry.setStaticConfig(true);
         entry.setBridgedVirtualInterface(false);
         entry.setAction(L2FibFilter.class);
+        return entry.build();
+    }
+
+    private L2FibEntry generateL2FibForwardEntry(final PhysAddress address) {
+        final L2FibEntryBuilder entry = new L2FibEntryBuilder();
+        entry.setKey(new L2FibEntryKey(address));
+        entry.setPhysAddress(address);
+        entry.setStaticConfig(true);
+        entry.setBridgedVirtualInterface(false);
+        entry.setAction(L2FibForward.class);
         entry.setOutgoingInterface(IFACE_NAME);
         return entry.build();
     }
 
+
     private void verifyL2FibAddDelWasInvoked(final L2FibAddDel expected) throws
             VppInvocationException {
         ArgumentCaptor<L2FibAddDel> argumentCaptor = ArgumentCaptor.forClass(L2FibAddDel.class);
@@ -117,24 +143,57 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest {
     }
 
     @Test
-    public void testCreate() throws Exception {
+    public void testCreateFilter() throws Exception {
         final long address_vpp = 0x0102030405060000L;
         final PhysAddress address = new PhysAddress("01:02:03:04:05:06");
-        final L2FibEntry entry = generateL2FibEntry(address);
+        final L2FibEntry entry = generateL2FibFilterEntry(address);
         final InstanceIdentifier<L2FibEntry> id = getL2FibEntryId(address);
 
         whenL2FibAddDelThenSuccess();
 
         customizer.writeCurrentAttributes(id, entry, writeContext);
 
-        verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 1));
+        verifyL2FibAddDelWasInvoked(generateL2FibAddDelFilterRequest(address_vpp, (byte) 1, NO_INTERFACE));
+    }
+
+    @Test
+    public void testCreateForward() throws Exception {
+        final long address_vpp = 0x0102030405060000L;
+        final PhysAddress address = new PhysAddress("01:02:03:04:05:06");
+        final L2FibEntry entry = generateL2FibForwardEntry(address);
+        final InstanceIdentifier<L2FibEntry> id = getL2FibEntryId(address);
+
+        whenL2FibAddDelThenSuccess();
+
+        customizer.writeCurrentAttributes(id, entry, writeContext);
+
+        verifyL2FibAddDelWasInvoked(generateL2FibAddDelForwardRequest(address_vpp, (byte) 1, IFACE_ID));
+    }
+
+    @Test
+    public void testCreateFilterFailed() throws Exception {
+        final long address_vpp = 0x1122334455660000L;
+        final PhysAddress address = new PhysAddress("11:22:33:44:55:66");
+        final L2FibEntry entry = generateL2FibFilterEntry(address);
+        final InstanceIdentifier<L2FibEntry> id = getL2FibEntryId(address);
+
+        whenL2FibAddDelThenFailure();
+
+        try {
+            customizer.writeCurrentAttributes(id, entry, writeContext);
+        } catch (WriteFailedException e) {
+            assertTrue(e.getCause() instanceof VppBaseCallException);
+            verifyL2FibAddDelWasInvoked(generateL2FibAddDelFilterRequest(address_vpp, (byte) 1, NO_INTERFACE));
+            return;
+        }
+        fail("WriteFailedException.CreateFailedException was expected");
     }
 
     @Test
-    public void testCreateFailed() throws Exception {
+    public void testCreateForwardFailed() throws Exception {
         final long address_vpp = 0x1122334455660000L;
         final PhysAddress address = new PhysAddress("11:22:33:44:55:66");
-        final L2FibEntry entry = generateL2FibEntry(address);
+        final L2FibEntry entry = generateL2FibForwardEntry(address);
         final InstanceIdentifier<L2FibEntry> id = getL2FibEntryId(address);
 
         whenL2FibAddDelThenFailure();
@@ -143,7 +202,7 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest {
             customizer.writeCurrentAttributes(id, entry, writeContext);
         } catch (WriteFailedException e) {
             assertTrue(e.getCause() instanceof VppBaseCallException);
-            verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 1));
+            verifyL2FibAddDelWasInvoked(generateL2FibAddDelForwardRequest(address_vpp, (byte) 1, IFACE_ID));
             return;
         }
         fail("WriteFailedException.CreateFailedException was expected");
@@ -156,24 +215,58 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest {
     }
 
     @Test
-    public void testDelete() throws Exception {
+    public void testDeleteFilter() throws Exception {
         final long address_vpp = 0x1122334455660000L;
         final PhysAddress address = new PhysAddress("11:22:33:44:55:66");
-        final L2FibEntry entry = generateL2FibEntry(address);
+        final L2FibEntry entry = generateL2FibFilterEntry(address);
         final InstanceIdentifier<L2FibEntry> id = getL2FibEntryId(address);
 
         whenL2FibAddDelThenSuccess();
 
         customizer.deleteCurrentAttributes(id, entry, writeContext);
 
-        verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 0));
+        verifyL2FibAddDelWasInvoked(generateL2FibAddDelFilterRequest(address_vpp, (byte) 0, NO_INTERFACE));
+    }
+
+    @Test
+    public void testDeleteForward() throws Exception {
+        final long address_vpp = 0x1122334455660000L;
+        final PhysAddress address = new PhysAddress("11:22:33:44:55:66");
+        final L2FibEntry entry = generateL2FibForwardEntry(address);
+        final InstanceIdentifier<L2FibEntry> id = getL2FibEntryId(address);
+
+        whenL2FibAddDelThenSuccess();
+
+        customizer.deleteCurrentAttributes(id, entry, writeContext);
+
+        verifyL2FibAddDelWasInvoked(generateL2FibAddDelForwardRequest(address_vpp, (byte) 0, IFACE_ID));
+    }
+
+
+    @Test
+    public void testDeleteFilterFailed() throws Exception {
+        final long address_vpp = 0x0102030405060000L;
+        final PhysAddress address = new PhysAddress("01:02:03:04:05:06");
+        final L2FibEntry entry = generateL2FibFilterEntry(address);
+        final InstanceIdentifier<L2FibEntry> id = getL2FibEntryId(address);
+
+        whenL2FibAddDelThenFailure();
+
+        try {
+            customizer.deleteCurrentAttributes(id, entry, writeContext);
+        } catch (WriteFailedException e) {
+            assertTrue(e.getCause() instanceof VppBaseCallException);
+            verifyL2FibAddDelWasInvoked(generateL2FibAddDelFilterRequest(address_vpp, (byte) 0, NO_INTERFACE));
+            return;
+        }
+        fail("WriteFailedException.DeleteFailedException was expected");
     }
 
     @Test
-    public void testDeleteFailed() throws Exception {
+    public void testDeleteForwardFailed() throws Exception {
         final long address_vpp = 0x0102030405060000L;
         final PhysAddress address = new PhysAddress("01:02:03:04:05:06");
-        final L2FibEntry entry = generateL2FibEntry(address);
+        final L2FibEntry entry = generateL2FibForwardEntry(address);
         final InstanceIdentifier<L2FibEntry> id = getL2FibEntryId(address);
 
         whenL2FibAddDelThenFailure();
@@ -182,7 +275,7 @@ public class L2FibEntryCustomizerTest extends WriterCustomizerTest {
             customizer.deleteCurrentAttributes(id, entry, writeContext);
         } catch (WriteFailedException e) {
             assertTrue(e.getCause() instanceof VppBaseCallException);
-            verifyL2FibAddDelWasInvoked(generateL2FibAddDelRequest(address_vpp, (byte) 0));
+            verifyL2FibAddDelWasInvoked(generateL2FibAddDelForwardRequest(address_vpp, (byte) 0, IFACE_ID));
             return;
         }
         fail("WriteFailedException.DeleteFailedException was expected");