HC2VPP-344: Add FIB table management for routing 93/13093/6
authorMichal Cmarada <[email protected]>
Fri, 22 Jun 2018 09:02:27 +0000 (11:02 +0200)
committerMarek Gradzki <[email protected]>
Fri, 22 Jun 2018 10:53:36 +0000 (10:53 +0000)
- update models with FIB table management
- fixes implementation for FIB table management

Change-Id: I5cf397d6e827cb14df970e14ee268ef870931bd4
Signed-off-by: Michal Cmarada <[email protected]>
20 files changed:
routing/routing-api/pom.xml
routing/routing-api/src/main/yang/[email protected]
routing/routing-api/src/main/yang/[email protected]
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/ControlPlaneProtocolCustomizer.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/trait/Ipv4RoutePathParser.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/trait/Ipv6RoutePathParser.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizer.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizer.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizer.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/TableLookupRequestFactory.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/trait/RouteRequestProducer.java
routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/RoutingModuleTest.java
routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizerTest.java
routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv4RouteCustomizerTest.java
routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/Ipv6RouteCustomizerTest.java
routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/RouteCustomizerTest.java [new file with mode: 0644]
routing/routing-impl/src/test/resources/init/config-data.json [deleted file]
routing/routing-impl/src/test/resources/init/state-data.json [deleted file]
routing/routing_postman_collection.json [changed mode: 0644->0755]

index 799c968..e408fb8 100644 (file)
             <version>${project.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>io.fd.hc2vpp.fib.management</groupId>
+            <artifactId>fib-management-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
         <dependency>
             <groupId>com.google.code.findbugs</groupId>
             <artifactId>jsr305</artifactId>
index cf26a1b..0160843 100644 (file)
@@ -33,11 +33,9 @@ module vpp-routing-types {
         description "Initial revision.";
     }
 
-    /*** Collection of types related to VPP routing ***/
-
-    typedef vni-reference {
-        type uint32;
-        description "Vrf index reference";
+    import vpp-fib-table-management {
+        prefix fib-management;
+        revision-date 2018-05-21;
     }
 
     /*** Groupings ***/
@@ -51,10 +49,14 @@ module vpp-routing-types {
 
     grouping table-lookup-case-params {
         leaf secondary-vrf {
-            type vni-reference;
+            type fib-management:fib-table-list-ref;
             mandatory true;
             description "Secondary vrf used to lookup in";
         }
+        leaf address-family {
+            type fib-management:address-family-type;
+            description "Address family reference for secondary vrf.";
+        }
         // uses special deaggregation address every time : 0.0.0.0
     }
 }
index aad069b..5bb9391 100644 (file)
@@ -16,9 +16,9 @@ module vpp-routing {
         revision-date 2018-03-13;
     }
 
-    import vpp-routing-types {
-        prefix vpp-routing-types;
-        revision-date 2018-04-06;
+    import vpp-fib-table-management {
+        prefix fib-management;
+        revision-date 2018-05-21;
     }
 
     organization
@@ -70,10 +70,14 @@ module vpp-routing {
     grouping vpp-routing-protocol-attributes{
         //vrf_id
         leaf primary-vrf{
-            type vpp-routing-types:vni-reference;
+            type fib-management:fib-table-list-ref;
             mandatory true;
             description "Main vrf associated to route";
         }
+        leaf address-family {
+            type fib-management:address-family-type;
+            description "Address family reference for primary vrf.";
+        }
     }
 
     augment /ietf-r:routing/ietf-r:control-plane-protocols/ietf-r:control-plane-protocol{
index 372da27..deb32d3 100644 (file)
@@ -40,7 +40,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.RoutingProtocolVppAttr;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.RoutingProtocolVppAttrBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.routing.control.plane.protocols.control.plane.protocol.VppProtocolAttributesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.types.rev180406.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
 import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -133,6 +133,8 @@ final class ControlPlaneProtocolCustomizer
                         new VniReference(
                             Long.valueOf(routingProtocolContext.getIndex(key.getName(),
                                                                          readContext.getMappingContext()))))
+                        // address family is not being set because Control plane protocol can contain both IPv4 and IPv6
+                        // protocols. Address family is resolved by static route type.
                     .build())
                 .build())
             .build();
index f1217ee..b0b3347 100644 (file)
@@ -43,7 +43,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.next.hop.options.next.hop.list.next.hop.list.NextHopBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.ipv4.unicast.routing.rev180319.VppIpv4NextHopAugmentation;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.ipv4.unicast.routing.rev180319.VppIpv4NextHopAugmentationBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.types.rev180406.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
 
 public interface Ipv4RoutePathParser extends RouteMapper {
 
@@ -65,7 +66,9 @@ public interface Ipv4RoutePathParser extends RouteMapper {
     static NextHopOptions tableLookup() {
         return new TableLookupCaseBuilder()
                 // TODO - https://jira.fd.io/browse/VPP-994
-                .setSecondaryVrf(new VniReference(0L)).build();
+                .setSecondaryVrf(new VniReference(0L))
+                .setAddressFamily(Ipv4.class)
+                .build();
     }
 
     static SpecialNextHop specialHop(final FibPath singlePath) {
index 27b5edf..14dbc88 100644 (file)
@@ -43,7 +43,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.next.hop.options.next.hop.list.next.hop.list.NextHopBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.ipv6.unicast.routing.rev180319.VppIpv6NextHopAugmentation;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.ipv6.unicast.routing.rev180319.VppIpv6NextHopAugmentationBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.types.rev180406.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
 
 public interface Ipv6RoutePathParser extends RouteMapper {
 
@@ -65,7 +66,9 @@ public interface Ipv6RoutePathParser extends RouteMapper {
     static NextHopOptions tableLookup() {
         return new TableLookupCaseBuilder()
             // TODO - https://jira.fd.io/browse/VPP-994
-            .setSecondaryVrf(new VniReference(0L)).build();
+                .setSecondaryVrf(new VniReference(0L))
+                .setAddressFamily(Ipv6.class)
+                .build();
     }
 
     static SpecialNextHop specialHop(final FibPath fibPath) {
index b68a503..67a9073 100644 (file)
@@ -20,9 +20,8 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 
 import io.fd.hc2vpp.common.translate.util.NamingContext;
-import io.fd.hc2vpp.fib.management.services.FibTableService;
+import io.fd.hc2vpp.fib.management.FibManagementIIds;
 import io.fd.honeycomb.translate.MappingContext;
-import io.fd.honeycomb.translate.read.ReadFailedException;
 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.translate.write.WriteContext;
 import io.fd.honeycomb.translate.write.WriteFailedException;
@@ -31,66 +30,36 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocol;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocolKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.RoutingProtocolVppAttr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Customizer for handling of write operations for {@link ControlPlaneProtocol}
  */
 final class ControlPlaneProtocolCustomizer
         implements ListWriterCustomizer<ControlPlaneProtocol, ControlPlaneProtocolKey> {
-    private static final Logger LOG = LoggerFactory.getLogger(ControlPlaneProtocolCustomizer.class);
 
     private final NamingContext routingProtocolContext;
-    private final FibTableService fibTableService;
 
-    ControlPlaneProtocolCustomizer(@Nonnull final NamingContext routingProtocolContext,
-                                   FibTableService fibTableService) {
+    ControlPlaneProtocolCustomizer(@Nonnull final NamingContext routingProtocolContext) {
         this.routingProtocolContext = routingProtocolContext;
-        this.fibTableService = fibTableService;
     }
 
-    @Override
-    public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<ControlPlaneProtocol> instanceIdentifier,
-                                       @Nonnull final ControlPlaneProtocol routingProtocol,
-                                       @Nonnull final WriteContext writeContext)
-            throws WriteFailedException {
-        checkIsStatic(routingProtocol);
+    static Long extractTableId(final ControlPlaneProtocol protocol) {
+        final RoutingProtocolVppAttr vppAttr = protocol.getAugmentation(RoutingProtocolVppAttr.class);
 
-        final int tableId = extractTableId(routingProtocol);
-        final MappingContext mappingContext = writeContext.getMappingContext();
-        final String newProtocolName = routingProtocol.getName();
+        checkState(vppAttr != null && vppAttr.getVppProtocolAttributes() != null,
+                "Vpp routing protocol attributes not defined");
 
-        // enclosed in synchronized block to prevent change of state after containsName/before addName
-        synchronized (routingProtocolContext) {
-            if (!routingProtocolContext.containsName(tableId, mappingContext)) {
-                // Todo HC2VPP-317: A proper solution for Fib table management should be implemented. This is a
-                // temporary workaround.
+        return vppAttr.getVppProtocolAttributes().getPrimaryVrf().getValue();
+    }
 
-                // if not present in mapping,create assignment to table id, then create ip v4/v6 fib table on device
-                try {
-                    fibTableService.checkTableExist(tableId, writeContext.getModificationCache());
-                } catch (ReadFailedException e) {
-                    LOG.error("VRF Fib table read failed for table {} with iid: {}. Aborting write operation", tableId,
-                            instanceIdentifier);
-                    throw new WriteFailedException(instanceIdentifier, e);
-                } catch (FibTableService.FibTableDoesNotExistException e) {
-                    LOG.trace("VRF Fib table does not exist. creating new entry for Fib table.", e);
-                    // Write IPv4 and IPv6 Fib table for this VRF
-                    fibTableService.write(instanceIdentifier, tableId, "Vrf-IPv4-" + tableId, false);
-                    fibTableService.write(instanceIdentifier, tableId, "Vrf-IPv6-" + tableId, true);
-                }
-                routingProtocolContext.addName(tableId, newProtocolName, mappingContext);
-            } else {
-                // prevent to fail while restoring data(trying to remap already mapped name)
-                if (!newProtocolName.equals(routingProtocolContext.getName(tableId, mappingContext))) {
-                    throw new IllegalStateException(String.format(
-                            "An attempt to assign protocol %s to table id %s. Table id already assigned to protocol %s",
-                            newProtocolName, tableId, routingProtocolContext.getName(tableId, mappingContext)));
-                }
-            }
-        }
+    static boolean isTablePresent(@Nonnull final TableKey tableKey, @Nonnull final WriteContext writeContext) {
+        return writeContext.readAfter(FibManagementIIds.FM_FIB_TABLES.child(Table.class, tableKey)).isPresent();
     }
 
     @Override
@@ -108,12 +77,38 @@ final class ControlPlaneProtocolCustomizer
         checkArgument(routingProtocol.getType() == Static.class, "Only static routes are allowed");
     }
 
-    private int extractTableId(final ControlPlaneProtocol protocol) {
-        final RoutingProtocolVppAttr vppAttr = protocol.getAugmentation(RoutingProtocolVppAttr.class);
+    @Override
+    public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<ControlPlaneProtocol> instanceIdentifier,
+                                       @Nonnull final ControlPlaneProtocol routingProtocol,
+                                       @Nonnull final WriteContext writeContext)
+            throws WriteFailedException {
+        checkIsStatic(routingProtocol);
 
-        checkState(vppAttr != null && vppAttr.getVppProtocolAttributes() != null,
-                "Vpp routing protocol attributes not defined");
+        final Long tableId = extractTableId(routingProtocol);
+        final MappingContext mappingContext = writeContext.getMappingContext();
+        final String newProtocolName = routingProtocol.getName();
 
-        return vppAttr.getVppProtocolAttributes().getPrimaryVrf().getValue().intValue();
+        // enclosed in synchronized block to prevent change of state after containsName/before addName
+        synchronized (routingProtocolContext) {
+            if (!routingProtocolContext.containsName(tableId.intValue(), mappingContext)) {
+                // Protocol supports both IPv4/IPv6, therefore checking if at least one exists. Proper table is checked
+                // afterwards in Ipv6 or IPv4 customizers
+                if (!isTablePresent(new TableKey(Ipv4.class, new VniReference(tableId)), writeContext) &&
+                        !isTablePresent(new TableKey(Ipv6.class, new VniReference(tableId)), writeContext)) {
+                    throw new WriteFailedException(instanceIdentifier,
+                            String.format("VRF lookup table: %s not found for protocol: %s", tableId,
+                                    instanceIdentifier));
+                }
+                routingProtocolContext.addName(tableId.intValue(), newProtocolName, mappingContext);
+            } else {
+                // prevent to fail while restoring data(trying to remap already mapped name)
+                if (!newProtocolName.equals(routingProtocolContext.getName(tableId.intValue(), mappingContext))) {
+                    throw new IllegalStateException(String.format(
+                            "An attempt to assign protocol %s to table id %s. Table id already assigned to protocol %s",
+                            newProtocolName, tableId,
+                            routingProtocolContext.getName(tableId.intValue(), mappingContext)));
+                }
+            }
+        }
     }
 }
index 1eb249f..a9a058c 100644 (file)
@@ -16,6 +16,8 @@
 
 package io.fd.hc2vpp.routing.write;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
 import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
@@ -29,6 +31,7 @@ import io.fd.hc2vpp.routing.write.factory.TableLookupRequestFactory;
 import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
 import io.fd.honeycomb.translate.MappingContext;
 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
 import io.fd.honeycomb.translate.write.WriteContext;
 import io.fd.honeycomb.translate.write.WriteFailedException;
 import io.fd.vpp.jvpp.core.dto.IpAddDelRoute;
@@ -46,6 +49,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.next.hop.options.TableLookupCase;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.next.hop.options.next.hop.list.next.hop.list.NextHop;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocol;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -100,6 +105,18 @@ public class Ipv4RouteCustomizer extends FutureJVppCustomizer
                                        @Nonnull final WriteContext writeContext) throws WriteFailedException {
         final String parentProtocolName = instanceIdentifier.firstKeyOf(ControlPlaneProtocol.class).getName();
         final String routeName = routeNamesFactory.uniqueRouteName(parentProtocolName, route);
+        Optional<ControlPlaneProtocol> protocolOptional =
+                writeContext.readAfter(RWUtils.cutId(instanceIdentifier, ControlPlaneProtocol.class));
+        Preconditions.checkArgument(protocolOptional.isPresent(), "Control protocol cannot be null for route: {}",
+                instanceIdentifier);
+        TableKey key = new TableKey(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv4.class,
+                new VniReference(ControlPlaneProtocolCustomizer.extractTableId(protocolOptional.get())));
+
+        if (!ControlPlaneProtocolCustomizer.isTablePresent(key, writeContext)) {
+            throw new WriteFailedException(instanceIdentifier, "IPv4 FIB table does not exist!");
+        }
+
         writeRoute(instanceIdentifier, parentProtocolName, routeName, route, writeContext, true);
 
         // maps new route by next available index,
@@ -149,11 +166,8 @@ public class Ipv4RouteCustomizer extends FutureJVppCustomizer
         } else if (route.getNextHop().getNextHopOptions() instanceof SpecialNextHop) {
             writeSpecialHopRoute(identifier, route, parentProtocolName, writeContext, isAdd);
         } else if (route.getNextHop().getNextHopOptions() instanceof TableLookupCase) {
-            writeRoute(tableLookupRequestFactory.createV4TableLookupRouteRequest(isAdd,
-                                                                                 parentProtocolName,
-                                                                                 route,
-                                                                                 writeContext.getMappingContext()),
-                       identifier);
+            writeRoute(tableLookupRequestFactory
+                    .createV4TableLookupRouteRequest(isAdd, parentProtocolName, route, writeContext), identifier);
         } else {
             throw new IllegalArgumentException("Unsupported next-hop type");
         }
index e30c38f..7c7e89f 100644 (file)
@@ -17,6 +17,8 @@
 package io.fd.hc2vpp.routing.write;
 
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
 import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
@@ -30,6 +32,7 @@ import io.fd.hc2vpp.routing.write.factory.TableLookupRequestFactory;
 import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
 import io.fd.honeycomb.translate.MappingContext;
 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
 import io.fd.honeycomb.translate.write.WriteContext;
 import io.fd.honeycomb.translate.write.WriteFailedException;
 import io.fd.vpp.jvpp.core.dto.IpAddDelRoute;
@@ -47,6 +50,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.next.hop.options.TableLookupCase;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.next.hop.options.next.hop.list.next.hop.list.NextHop;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocol;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -102,6 +107,18 @@ public class Ipv6RouteCustomizer extends FutureJVppCustomizer
                                        @Nonnull final WriteContext writeContext) throws WriteFailedException {
         final String parentProtocolName = instanceIdentifier.firstKeyOf(ControlPlaneProtocol.class).getName();
         final String routeName = namesFactory.uniqueRouteName(parentProtocolName, route);
+        Optional<ControlPlaneProtocol> protocolOptional =
+                writeContext.readAfter(RWUtils.cutId(instanceIdentifier, ControlPlaneProtocol.class));
+        Preconditions.checkArgument(protocolOptional.isPresent(), "Control protocol cannot be null for route: {}",
+                instanceIdentifier);
+        TableKey key = new TableKey(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6.class,
+                new VniReference(ControlPlaneProtocolCustomizer.extractTableId(protocolOptional.get())));
+
+        if (!ControlPlaneProtocolCustomizer.isTablePresent(key, writeContext)) {
+            throw new WriteFailedException(instanceIdentifier, "Ipv6 FIB table does not exist!");
+        }
+
         writeRoute(instanceIdentifier, parentProtocolName, routeName, route, writeContext, true);
 
         // maps new route by next available index,
@@ -142,9 +159,8 @@ public class Ipv6RouteCustomizer extends FutureJVppCustomizer
         } else if (route.getNextHop().getNextHopOptions() instanceof SpecialNextHop) {
             writeSpecialHopRoute(identifier, route, parentProtocolName, writeContext, isAdd);
         } else if (route.getNextHop().getNextHopOptions() instanceof TableLookupCase) {
-            writeRoute(tableLookupRequestFactory.createV6TableLookupRouteRequest(isAdd, parentProtocolName, route,
-                                                                                 writeContext.getMappingContext()),
-                       identifier);
+            writeRoute(tableLookupRequestFactory
+                    .createV6TableLookupRouteRequest(isAdd, parentProtocolName, route, writeContext), identifier);
         } else {
             throw new IllegalArgumentException("Unsupported next-hop type");
         }
index 4af6f55..05d6916 100644 (file)
@@ -25,7 +25,6 @@ import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
-import io.fd.hc2vpp.fib.management.services.FibTableService;
 import io.fd.hc2vpp.routing.Ipv4RoutingNodes;
 import io.fd.hc2vpp.routing.Ipv6RoutingNodes;
 import io.fd.hc2vpp.routing.RoutingConfiguration;
@@ -63,9 +62,6 @@ public final class RoutingWriterFactory implements WriterFactory, Ipv4RoutingNod
     @Inject
     private RoutingConfiguration configuration;
 
-    @Inject
-    private FibTableService fibTableService;
-
     @Inject
     @Named("interface-context")
     private NamingContext interfaceContext;
@@ -93,7 +89,7 @@ public final class RoutingWriterFactory implements WriterFactory, Ipv4RoutingNod
                 new GenericWriter<>(RoutingIIds.ROUTING, new RoutingCustomizer()));
 
         registry.subtreeAdd(routingProtocolHandledChildren(),new GenericWriter<>(RoutingIIds.RT_CPS_CP,
-                new ControlPlaneProtocolCustomizer(routingProtocolContext, fibTableService)));
+                new ControlPlaneProtocolCustomizer(routingProtocolContext)));
 
         registry.subtreeAddAfter(ipv4RoutingHandledChildren(RoutingIIds.RT_CPS_CP_SR_SRV4_IPV4_RT_PARENT),
                                  new GenericWriter<>(RoutingIIds.RT_CPS_CP_SR_SRV4_IPV4_RT,
index 8a11adc..99b2b1f 100644 (file)
 package io.fd.hc2vpp.routing.write.factory;
 
 import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.fib.management.FibManagementIIds;
 import io.fd.hc2vpp.routing.write.factory.base.BasicHopRequestFactory;
 import io.fd.hc2vpp.routing.write.trait.RouteRequestProducer;
 import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
-import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.write.WriteContext;
 import io.fd.vpp.jvpp.core.dto.IpAddDelRoute;
 import java.util.Optional;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv4.Route;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.NextHopOptions;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.next.hop.options.TableLookupCase;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.ipv4.unicast.routing.rev180319.VppIpv4RouteAttributesAugmentation;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.ipv4.unicast.routing.rev180319.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv4.route.VppIpv4Route;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.ipv6.unicast.routing.rev180319.VppIpv6RouteAttributesAugmentation;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.ipv6.unicast.routing.rev180319.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv6.route.VppIpv6Route;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.VppRouteAttributes;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.types.rev180406.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableKey;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 
 public class TableLookupRequestFactory extends BasicHopRequestFactory implements RouteRequestProducer {
 
@@ -50,20 +55,27 @@ public class TableLookupRequestFactory extends BasicHopRequestFactory implements
     public IpAddDelRoute createV4TableLookupRouteRequest(final boolean add,
                                                          @Nonnull final String parentProtocolName,
                                                          @Nonnull final Route route,
-                                                         @Nonnull final MappingContext mappingContext) {
+                                                         @Nonnull final WriteContext writeContext) {
 
         final Ipv4Prefix prefix = route.getDestinationPrefix();
         final byte[] destinationAddress = ipv4AddressPrefixToArray(prefix);
         final byte destinationPrefix = extractPrefix(prefix);
-        final int primaryTableId = getRoutingProtocolContext().getIndex(parentProtocolName, mappingContext);
-        final byte secondaryTableId = Optional.ofNullable(route.getNextHop().getNextHopOptions())
+        final int primaryTableId = getRoutingProtocolContext().getIndex(parentProtocolName,
+                writeContext.getMappingContext());
+        final Long secondaryTableId = Optional.ofNullable(route.getNextHop().getNextHopOptions())
                 .filter(nextHopOptions -> nextHopOptions instanceof TableLookupCase)
                 .map(TableLookupCase.class::cast)
                 .map(TableLookupCase::getSecondaryVrf)
                 .map(VniReference::getValue)
-                .map(Long::byteValue)
                 .orElseThrow(() -> new IllegalArgumentException("Table lookup option not specified correctly"));
 
+        TableKey key = new TableKey(Ipv4.class, new VniReference(secondaryTableId));
+        KeyedInstanceIdentifier<Table, TableKey> fibIid = FibManagementIIds.FM_FIB_TABLES.child(Table.class, key);
+        if (!writeContext.readAfter(fibIid).isPresent()) {
+            throw new IllegalArgumentException(
+                    String.format("Lookup table: %s not found for route: %s", secondaryTableId, route));
+        }
+
         VppIpv4Route vppIpv4Route =
             route.getAugmentation(VppIpv4RouteAttributesAugmentation.class) != null ? route.getAugmentation(
                 VppIpv4RouteAttributesAugmentation.class).getVppIpv4Route() : null;
@@ -71,42 +83,53 @@ public class TableLookupRequestFactory extends BasicHopRequestFactory implements
         final Optional<String> optClassifyTable = Optional.ofNullable(vppIpv4Route)
                 .map(VppRouteAttributes::getClassifyTable);
         final byte classifyTableSet = booleanToByte(optClassifyTable.isPresent());
-        final byte classifyTableIndex = optClassifyTable.map(tableName -> classifyTableIndex(tableName, getVppClassifierContextManager(), mappingContext))
+        final byte classifyTableIndex = optClassifyTable
+                .map(tableName -> classifyTableIndex(tableName, getVppClassifierContextManager(),
+                        writeContext.getMappingContext()))
                 .map(Integer::byteValue)
                 .orElse(DEFAULT_CLASSIFY_TABLE_INDEX);
 
-        return flaglessAddDelRouteRequest(booleanToByte(add), ~0, DEAGRAGATION_ADDRESS, (byte) 0, (byte) 0, destinationAddress,
-                destinationPrefix, (byte) 0, primaryTableId, secondaryTableId, classifyTableIndex, classifyTableSet);
+        return flaglessAddDelRouteRequest(booleanToByte(add), ~0, DEAGRAGATION_ADDRESS, (byte) 0, (byte) 0,
+                destinationAddress, destinationPrefix, (byte) 0, primaryTableId, secondaryTableId.intValue(),
+                classifyTableIndex, classifyTableSet);
     }
 
     public IpAddDelRoute createV6TableLookupRouteRequest(final boolean add,
                                                          @Nonnull final String parentProtocolName,
                                                          @Nonnull final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv6.Route route,
-                                                         @Nonnull final MappingContext mappingContext) {
+                                                         @Nonnull final WriteContext writeContext) {
 
         final Ipv6Prefix prefix = route.getDestinationPrefix();
         final byte[] destinationAddress = ipv6AddressPrefixToArray(prefix);
         final byte destinationPrefix = extractPrefix(prefix);
-        final int primaryTableId = getRoutingProtocolContext().getIndex(parentProtocolName, mappingContext);
-        final byte secondaryTableId = Optional.ofNullable(route.getNextHop().getNextHopOptions())
+        final int primaryTableId =
+                getRoutingProtocolContext().getIndex(parentProtocolName, writeContext.getMappingContext());
+        final Long secondaryTableId = Optional.ofNullable(route.getNextHop().getNextHopOptions())
                 .filter(nextHopOptions -> nextHopOptions instanceof TableLookupCase)
                 .map(TableLookupCase.class::cast)
                 .map(TableLookupCase::getSecondaryVrf)
                 .map(VniReference::getValue)
-                .map(Long::byteValue)
                 .orElseThrow(() -> new IllegalArgumentException("Table lookup option not specified correctly"));
 
+        TableKey key = new TableKey(Ipv6.class, new VniReference(secondaryTableId));
+        KeyedInstanceIdentifier<Table, TableKey> fibIid = FibManagementIIds.FM_FIB_TABLES.child(Table.class, key);
+        if (!writeContext.readAfter(fibIid).isPresent()) {
+            throw new IllegalArgumentException(
+                    String.format("Lookup table: %s not found for route: %s", secondaryTableId, route));
+        }
+
         VppIpv6Route vppIpv6Route = route.getAugmentation(VppIpv6RouteAttributesAugmentation.class) != null
             ? route.getAugmentation(VppIpv6RouteAttributesAugmentation.class).getVppIpv6Route() : null;
 
         final Optional<String> optClassifyTable = Optional.ofNullable(vppIpv6Route)
                 .map(VppRouteAttributes::getClassifyTable);
         final byte classifyTableSet = booleanToByte(optClassifyTable.isPresent());
-        final byte classifyTableIndex = optClassifyTable.map(tableName -> classifyTableIndex(tableName, getVppClassifierContextManager(), mappingContext))
-                .map(Integer::byteValue)
-                .orElse(DEFAULT_CLASSIFY_TABLE_INDEX);
+        final byte classifyTableIndex = optClassifyTable
+                .map(tableName -> classifyTableIndex(tableName, getVppClassifierContextManager(),
+                        writeContext.getMappingContext())).map(Integer::byteValue).orElse(DEFAULT_CLASSIFY_TABLE_INDEX);
 
-        return flaglessAddDelRouteRequest(booleanToByte(add), ~0, DEAGRAGATION_ADDRESS, (byte) 0, (byte) 1, destinationAddress,
-                destinationPrefix, (byte) 0, primaryTableId, secondaryTableId, classifyTableIndex, classifyTableSet);
+        return flaglessAddDelRouteRequest(booleanToByte(add), ~0, DEAGRAGATION_ADDRESS, (byte) 0, (byte) 1,
+                destinationAddress, destinationPrefix, (byte) 0, primaryTableId, secondaryTableId.intValue(),
+                classifyTableIndex, classifyTableSet);
     }
 }
index f1a97aa..449a925 100644 (file)
@@ -17,8 +17,6 @@
 package io.fd.hc2vpp.routing.write.trait;
 
 import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.Objects.isNull;
 import static org.apache.commons.lang3.StringUtils.isNotEmpty;
 
 import com.google.common.collect.ImmutableSet.Builder;
@@ -32,7 +30,6 @@ import java.util.Set;
 import java.util.regex.Pattern;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.types.rev180406.VniReference;
 
 
 /**
@@ -49,16 +46,6 @@ public interface RouteRequestProducer extends ByteDataTranslator, AddressTransla
 
     int MPLS_LABEL_INVALID = 0x100000;
 
-    default int mandatoryVni(final VniReference vniReference) {
-        return checkNotNull(vniReference, "Vni reference cannot be null").getValue().intValue();
-    }
-
-    default int optionalVni(final VniReference vniReference) {
-        return isNull(vniReference)
-                ? DEFAULT_VNI
-                : vniReference.getValue().intValue();
-    }
-
     default byte extractPrefix(final String value) {
         checkArgument(
                 allowedPrefixPatterns.stream().anyMatch(pattern -> Pattern.compile(pattern).matcher(value).matches()),
index a12d0e0..679b903 100644 (file)
@@ -31,7 +31,6 @@ import com.google.inject.name.Named;
 import com.google.inject.testing.fieldbinder.Bind;
 import com.google.inject.testing.fieldbinder.BoundFieldModule;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
-import io.fd.hc2vpp.fib.management.services.FibTableService;
 import io.fd.hc2vpp.routing.read.RoutingReaderFactory;
 import io.fd.hc2vpp.routing.write.RoutingWriterFactory;
 import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
@@ -73,10 +72,6 @@ public class RoutingModuleTest {
     @Mock
     private FutureJVppCore futureJVppCore;
 
-    @Bind
-    @Mock
-    private FibTableService fibTableService;
-
     @Inject
     private Set<ReaderFactory> readerFactories = new HashSet<>();
 
index c96e313..8d49f81 100644 (file)
@@ -20,45 +20,68 @@ import static io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper.ROUTE_PROTOC
 import static io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper.ROUTE_PROTOCOL_NAME_2;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
 import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
-import io.fd.hc2vpp.fib.management.services.FibTableService;
+import io.fd.hc2vpp.fib.management.FibManagementIIds;
 import io.fd.honeycomb.translate.write.WriteFailedException;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mock;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.Direct;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.Static;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.ControlPlaneProtocols;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocol;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocolBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocolKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.RoutingProtocolVppAttr;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.RoutingProtocolVppAttrBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.routing.control.plane.protocols.control.plane.protocol.VppProtocolAttributesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.types.rev180406.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 
 public class ControlPlaneProtocolCustomizerTest extends WriterCustomizerTest {
 
+    private static final VniReference VRF = new VniReference(1L);
+    private static final VniReference INVALID_VRF = new VniReference(3L);
+    private static final String INVALID_TABLE_PROTOCOL_1 = "invalid-table-protocol-1";
     private InstanceIdentifier<ControlPlaneProtocol> validId;
+    private InstanceIdentifier<ControlPlaneProtocol> invalidIid;
     private ControlPlaneProtocol validData;
     private ControlPlaneProtocol validData2;
     private ControlPlaneProtocol invalidData;
+    private ControlPlaneProtocol invalidTableData;
     private ControlPlaneProtocolCustomizer customizer;
     private NamingContext routingProtocolContext;
 
-    @Mock
-    protected FibTableService fibTableService;
-
     @Before
     public void init() {
         validId = InstanceIdentifier.create(ControlPlaneProtocol.class);
+        invalidIid = InstanceIdentifier.create(ControlPlaneProtocols.class)
+                .child(ControlPlaneProtocol.class,
+                        new ControlPlaneProtocolKey(INVALID_TABLE_PROTOCOL_1, Static.class));
+        invalidTableData = new ControlPlaneProtocolBuilder()
+                .setName(INVALID_TABLE_PROTOCOL_1)
+                .setType(Static.class)
+                .addAugmentation(RoutingProtocolVppAttr.class, new RoutingProtocolVppAttrBuilder()
+                        .setVppProtocolAttributes(new VppProtocolAttributesBuilder()
+                                .setPrimaryVrf(INVALID_VRF)
+                                .build())
+                        .build())
+                .build();
         validData = new ControlPlaneProtocolBuilder()
                 .setName(ROUTE_PROTOCOL_NAME)
                 .setType(Static.class)
                 .addAugmentation(RoutingProtocolVppAttr.class, new RoutingProtocolVppAttrBuilder()
                         .setVppProtocolAttributes(new VppProtocolAttributesBuilder()
-                                .setPrimaryVrf(new VniReference(1L))
+                                .setPrimaryVrf(VRF)
                                 .build())
                         .build())
                 .build();
@@ -68,7 +91,7 @@ public class ControlPlaneProtocolCustomizerTest extends WriterCustomizerTest {
                 .setType(Static.class)
                 .addAugmentation(RoutingProtocolVppAttr.class, new RoutingProtocolVppAttrBuilder()
                         .setVppProtocolAttributes(new VppProtocolAttributesBuilder()
-                                .setPrimaryVrf(new VniReference(1L))
+                                .setPrimaryVrf(VRF)
                                 .build())
                         .build())
                 .build();
@@ -78,7 +101,32 @@ public class ControlPlaneProtocolCustomizerTest extends WriterCustomizerTest {
                 .build();
 
         routingProtocolContext = new NamingContext("routing-protocol", "routing-protocol-context");
-        customizer = new ControlPlaneProtocolCustomizer(routingProtocolContext, fibTableService);
+        customizer = new ControlPlaneProtocolCustomizer(routingProtocolContext);
+        TableKey keyV4 = new TableKey(Ipv4.class, VRF);
+        TableKey keyV6 = new TableKey(Ipv6.class, VRF);
+        KeyedInstanceIdentifier<Table, TableKey> vrfIidV4 = FibManagementIIds.FM_FIB_TABLES.child(Table.class, keyV4);
+        KeyedInstanceIdentifier<Table, TableKey> vrfIidV6 = FibManagementIIds.FM_FIB_TABLES.child(Table.class, keyV6);
+        TableKey invalidKeyV4 = new TableKey(Ipv4.class, INVALID_VRF);
+        TableKey invalidKeyV6 = new TableKey(Ipv6.class, INVALID_VRF);
+        KeyedInstanceIdentifier<Table, TableKey> invalidVrfIidV4 =
+                FibManagementIIds.FM_FIB_TABLES.child(Table.class, invalidKeyV4);
+        KeyedInstanceIdentifier<Table, TableKey> invalidVrfIidV6 =
+                FibManagementIIds.FM_FIB_TABLES.child(Table.class, invalidKeyV6);
+        when(writeContext.readAfter(vrfIidV4)).thenReturn(Optional.of(
+                new TableBuilder().setKey(keyV4).setAddressFamily(keyV4.getAddressFamily())
+                        .setTableId(keyV4.getTableId()).setName("VRF-IPV4-1").build()));
+        when(writeContext.readAfter(vrfIidV6)).thenReturn(Optional.of(
+                new TableBuilder().setKey(keyV6).setAddressFamily(keyV6.getAddressFamily())
+                        .setTableId(keyV6.getTableId()).setName("VRF-IPV6-1").build()));
+        when(writeContext.readAfter(invalidVrfIidV4)).thenReturn(Optional.absent());
+        when(writeContext.readAfter(invalidVrfIidV6)).thenReturn(Optional.absent());
+    }
+
+    @Test(expected = WriteFailedException.class)
+    public void testWriteInvalid() throws WriteFailedException {
+        noMappingDefined(mappingContext, INVALID_TABLE_PROTOCOL_1, "routing-protocol-context");
+        customizer.writeCurrentAttributes(invalidIid, invalidTableData, writeContext);
+
     }
 
     @Test
index 41a1ae6..36e0aed 100644 (file)
@@ -19,21 +19,17 @@ package io.fd.hc2vpp.routing.write;
 import static io.fd.hc2vpp.routing.Ipv4RouteData.FIRST_ADDRESS_AS_ARRAY;
 import static io.fd.hc2vpp.routing.Ipv4RouteData.SECOND_ADDRESS_AS_ARRAY;
 import static io.fd.hc2vpp.routing.helpers.InterfaceTestHelper.INTERFACE_INDEX;
-import static io.fd.hc2vpp.routing.helpers.InterfaceTestHelper.INTERFACE_NAME;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
-import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
-import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
-import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper;
-import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper;
-import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper;
+import io.fd.hc2vpp.fib.management.FibManagementIIds;
 import io.fd.hc2vpp.routing.naming.Ipv4RouteNamesFactory;
-import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
 import io.fd.honeycomb.test.tools.HoneycombTestRunner;
 import io.fd.honeycomb.test.tools.annotations.InjectTestData;
 import io.fd.honeycomb.translate.write.WriteFailedException;
@@ -42,7 +38,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
-import org.mockito.Mock;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev180313.StaticRoutes1;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.Ipv4;
@@ -50,55 +45,67 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicas
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv4.RouteBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv4.RouteKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv4.route.NextHopBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.Static;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.next.hop.options.TableLookupCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.ControlPlaneProtocols;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocol;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocolKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.control.plane.protocol.StaticRoutes;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.types.rev180406.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 
 @RunWith(HoneycombTestRunner.class)
-public class Ipv4RouteCustomizerTest extends WriterCustomizerTest
-        implements ClassifyTableTestHelper, RoutingRequestTestHelper, SchemaContextTestHelper {
+public class Ipv4RouteCustomizerTest extends RouteCustomizerTest {
 
-    private static final int ROUTE_PROTOCOL_INDEX = 1;
-    @Captor
-    private ArgumentCaptor<IpAddDelRoute> requestCaptor;
+    private static final TableKey
+            SEC_TABLE_KEY = new TableKey(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv4.class,
+            SEC_TABLE_ID);
+    private static final Table
+            IPV4_TABLE = new TableBuilder().setName("VRF-IPV4-4")
+            .setKey(SEC_TABLE_KEY).setTableId(SEC_TABLE_KEY.getTableId())
+            .setAddressFamily(SEC_TABLE_KEY.getAddressFamily()).build();
 
-    @Mock
-    private VppClassifierContextManager classifyManager;
+    private static final InstanceIdentifier<Route> ROUTE_IID = CONTROL_PROTOCOL_IID
+            .child(StaticRoutes.class)
+            .augmentation(StaticRoutes1.class)
+            .child(Ipv4.class)
+            .child(Route.class);
+    private static final InstanceIdentifier<Route> ROUTE_INVALID_IID = CONTROL_PROTOCOL_INVALID_IID
+            .child(StaticRoutes.class)
+            .augmentation(StaticRoutes1.class)
+            .child(Ipv4.class)
+            .child(Route.class);
 
-    @Mock
-    private MultiNamingContext routeHopContext;
+    @Captor
+    private ArgumentCaptor<IpAddDelRoute> requestCaptor;
 
     private Ipv4RouteCustomizer customizer;
-    private InstanceIdentifier<Route> validId;
     private Ipv4RouteNamesFactory namesFactory;
-    private NamingContext routingProtocolContext;
 
     @Override
     protected void setUpTest() throws Exception {
-        NamingContext interfaceContext = new NamingContext("interface", "interface-context");
-        routingProtocolContext = new NamingContext("routing-protocol", "routing-protocol-context");
-        customizer = new Ipv4RouteCustomizer(api, interfaceContext,
-                new NamingContext("route", "route-context"),
+        super.setUpTest();
+        customizer = new Ipv4RouteCustomizer(api, interfaceContext, new NamingContext("route", "route-context"),
                 routingProtocolContext, routeHopContext, classifyManager);
+        namesFactory = new Ipv4RouteNamesFactory(interfaceContext, routingProtocolContext);
 
-        validId = InstanceIdentifier.create(ControlPlaneProtocols.class)
-                .child(ControlPlaneProtocol.class, new ControlPlaneProtocolKey(ROUTE_PROTOCOL_NAME, Static.class))
-                .child(StaticRoutes.class)
-                .augmentation(StaticRoutes1.class)
-                .child(Ipv4.class)
-                .child(Route.class);
+        KeyedInstanceIdentifier<Table, TableKey> secondaryFibIid =
+                FibManagementIIds.FM_FIB_TABLES.child(Table.class, SEC_TABLE_KEY);
 
-        namesFactory = new Ipv4RouteNamesFactory(interfaceContext, routingProtocolContext);
+        when(writeContext.readAfter(secondaryFibIid)).thenReturn(Optional.of(IPV4_TABLE));
+    }
+
+    @Test(expected = WriteFailedException.class)
+    public void testWriteSingleHopInvalid(
+            @InjectTestData(resourcePath = "/ipv4/simplehop/simpleHopRouteWithClassifier.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
+            throws WriteFailedException {
+        final Route route1 = getIpv4RouteWithId(route, new Ipv4Prefix("192.168.2.1/24"));
+        noMappingDefined(mappingContext, namesFactory.uniqueRouteName(ROUTE_PROTOCOL_INVALID_NAME, route1),
+                "route-context");
 
-        defineMapping(mappingContext, INTERFACE_NAME, INTERFACE_INDEX, "interface-context");
-        defineMapping(mappingContext, ROUTE_PROTOCOL_NAME, ROUTE_PROTOCOL_INDEX, "routing-protocol-context");
-        addMapping(classifyManager, CLASSIFY_TABLE_NAME, CLASSIFY_TABLE_INDEX, mappingContext);
-        whenAddRouteThenSuccess(api);
+        customizer.writeCurrentAttributes(ROUTE_INVALID_IID, route1, writeContext);
+        verifyInvocation(0, ImmutableList.of(), api, requestCaptor);
     }
 
     @Test
@@ -108,10 +115,10 @@ public class Ipv4RouteCustomizerTest extends WriterCustomizerTest
         final Route route1 = getIpv4RouteWithId(route, new Ipv4Prefix("192.168.2.1/24"));
         noMappingDefined(mappingContext, namesFactory.uniqueRouteName(ROUTE_PROTOCOL_NAME, route1), "route-context");
 
-        customizer.writeCurrentAttributes(validId, route1, writeContext);
+        customizer.writeCurrentAttributes(ROUTE_IID, route1, writeContext);
         verifyInvocation(1, ImmutableList
                         .of(desiredFlaglessResult(1, 0, 0, FIRST_ADDRESS_AS_ARRAY, 24,
-                                SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 0, ROUTE_PROTOCOL_INDEX, 0,
+                                SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 0, TABLE_ID.intValue(), 0,
                                 CLASSIFY_TABLE_INDEX, 1)),
                 api, requestCaptor);
     }
@@ -125,13 +132,15 @@ public class Ipv4RouteCustomizerTest extends WriterCustomizerTest
                 .setNextHop(new NextHopBuilder().setNextHopOptions(
                     new TableLookupCaseBuilder()
                         .setSecondaryVrf(new VniReference(4L))
+                            .setAddressFamily(
+                                    org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv4.class)
                                 .build()).build())
                 .build();
         noMappingDefined(mappingContext, namesFactory.uniqueRouteName(ROUTE_PROTOCOL_NAME, route), "route-context");
-        customizer.writeCurrentAttributes(validId, route, writeContext);
+        customizer.writeCurrentAttributes(ROUTE_IID, route, writeContext);
         verifyInvocation(1, ImmutableList
                         .of(desiredFlaglessResult(1, 0, 0, FIRST_ADDRESS_AS_ARRAY, 24,
-                                new byte[4], ~0, 0, ROUTE_PROTOCOL_INDEX, 4,
+                                new byte[4], ~0, 0, TABLE_ID.intValue(), 4,
                                 0, 0)),
                 api, requestCaptor);
     }
@@ -144,14 +153,14 @@ public class Ipv4RouteCustomizerTest extends WriterCustomizerTest
         final Route route1 = getIpv4RouteWithId(route, new Ipv4Prefix("192.168.2.1/24"));
         noMappingDefined(mappingContext, namesFactory.uniqueRouteName(ROUTE_PROTOCOL_NAME, route1), "route-context");
 
-        customizer.writeCurrentAttributes(validId, route1, writeContext);
+        customizer.writeCurrentAttributes(ROUTE_IID, route1, writeContext);
         verifyInvocation(2,
                 ImmutableList.of(
                         desiredFlaglessResult(1, 0, 1, FIRST_ADDRESS_AS_ARRAY, 24,
-                                FIRST_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 2, ROUTE_PROTOCOL_INDEX, 0,
+                                FIRST_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 2, TABLE_ID.intValue(), 0,
                                 CLASSIFY_TABLE_INDEX, 1),
                         desiredFlaglessResult(1, 0, 1, FIRST_ADDRESS_AS_ARRAY, 24,
-                                SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 3, ROUTE_PROTOCOL_INDEX, 0,
+                                SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 3, TABLE_ID.intValue(), 0,
                                 CLASSIFY_TABLE_INDEX, 1)), api,
                 requestCaptor);
 
@@ -174,10 +183,10 @@ public class Ipv4RouteCustomizerTest extends WriterCustomizerTest
         final Route route1 = getIpv4RouteWithId(route, new Ipv4Prefix("192.168.2.1/24"));
         noMappingDefined(mappingContext, namesFactory.uniqueRouteName(ROUTE_PROTOCOL_NAME, route1), "route-context");
 
-        customizer.writeCurrentAttributes(validId, route1, writeContext);
+        customizer.writeCurrentAttributes(ROUTE_IID, route1, writeContext);
         verifyInvocation(1, ImmutableList
                         .of(desiredSpecialResult(1, 0, FIRST_ADDRESS_AS_ARRAY, 24, 1, 0, 0, 0,
-                                                 ROUTE_PROTOCOL_INDEX, 0)),
+                                TABLE_ID.intValue(), 0)),
                          api, requestCaptor);
     }
 
@@ -185,7 +194,7 @@ public class Ipv4RouteCustomizerTest extends WriterCustomizerTest
     public void testUpdate(
             @InjectTestData(resourcePath = "/ipv4/specialhop/specialHopRouteBlackhole.json", id = STATIC_ROUTE_PATH) StaticRoutes route) {
         try {
-            customizer.updateCurrentAttributes(validId,
+            customizer.updateCurrentAttributes(ROUTE_IID,
                                                new RouteBuilder().build(),
                                                getIpv4RouteWithId(route,
                                                                   new Ipv4Prefix("192.168.2.1/24")), writeContext);
@@ -202,13 +211,13 @@ public class Ipv4RouteCustomizerTest extends WriterCustomizerTest
     public void testDeleteSingleHop(
             @InjectTestData(resourcePath = "/ipv4/simplehop/simpleHopRouteWithClassifier.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
             throws WriteFailedException {
-        customizer.deleteCurrentAttributes(validId,
+        customizer.deleteCurrentAttributes(ROUTE_IID,
                                            getIpv4RouteWithId(route,
                                                               new Ipv4Prefix("192.168.2.1/24")), writeContext);
         verifyInvocation(1, ImmutableList
                 .of(desiredFlaglessResult(0, 0, 0, FIRST_ADDRESS_AS_ARRAY, 24,
                         SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX,
-                        0, ROUTE_PROTOCOL_INDEX, 0, CLASSIFY_TABLE_INDEX, 1)),
+                        0, TABLE_ID.intValue(), 0, CLASSIFY_TABLE_INDEX, 1)),
                          api, requestCaptor);
     }
 
@@ -219,14 +228,14 @@ public class Ipv4RouteCustomizerTest extends WriterCustomizerTest
         final Route route1 = getIpv4RouteWithId(route, new Ipv4Prefix("192.168.2.1/24"));
         noMappingDefined(mappingContext, namesFactory.uniqueRouteName(ROUTE_PROTOCOL_NAME, route1), "route-context");
 
-        customizer.deleteCurrentAttributes(validId, route1, writeContext);
+        customizer.deleteCurrentAttributes(ROUTE_IID, route1, writeContext);
         verifyInvocation(2,
                 ImmutableList.of(
                         desiredFlaglessResult(0, 0, 1, FIRST_ADDRESS_AS_ARRAY, 24,
-                                FIRST_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 2, ROUTE_PROTOCOL_INDEX, 0,
+                                FIRST_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 2, TABLE_ID.intValue(), 0,
                                 CLASSIFY_TABLE_INDEX, 1),
                         desiredFlaglessResult(0, 0, 1, FIRST_ADDRESS_AS_ARRAY, 24,
-                                new byte[]{-64, -88, 2, 2}, INTERFACE_INDEX, 3, ROUTE_PROTOCOL_INDEX, 0,
+                                new byte[]{-64, -88, 2, 2}, INTERFACE_INDEX, 3, TABLE_ID.intValue(), 0,
                                 CLASSIFY_TABLE_INDEX, 1)), api, requestCaptor);
 
         verify(routeHopContext, times(1))
@@ -245,11 +254,12 @@ public class Ipv4RouteCustomizerTest extends WriterCustomizerTest
     public void testDeleteSpecialHop(
             @InjectTestData(resourcePath = "/ipv4/specialhop/specialHopRouteBlackhole.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
             throws WriteFailedException {
-        customizer.deleteCurrentAttributes(validId, getIpv4RouteWithId(route, new Ipv4Prefix("192.168.2.1/24")), writeContext);
+        customizer.deleteCurrentAttributes(ROUTE_IID, getIpv4RouteWithId(route, new Ipv4Prefix("192.168.2.1/24")),
+                writeContext);
 
         verifyInvocation(1,
                 ImmutableList.of(desiredSpecialResult(0, 0, FIRST_ADDRESS_AS_ARRAY, 24, 1, 0, 0, 0,
-                                                      ROUTE_PROTOCOL_INDEX, 0)),
+                        TABLE_ID.intValue(), 0)),
                          api, requestCaptor);
     }
 }
index 171b597..0d78ca5 100644 (file)
 package io.fd.hc2vpp.routing.write;
 
 import static io.fd.hc2vpp.routing.helpers.InterfaceTestHelper.INTERFACE_INDEX;
-import static io.fd.hc2vpp.routing.helpers.InterfaceTestHelper.INTERFACE_NAME;
+import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
-import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
-import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
-import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.fib.management.FibManagementIIds;
 import io.fd.hc2vpp.routing.Ipv6RouteData;
-import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper;
-import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper;
-import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper;
 import io.fd.hc2vpp.routing.naming.Ipv6RouteNamesFactory;
-import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
 import io.fd.honeycomb.test.tools.HoneycombTestRunner;
 import io.fd.honeycomb.test.tools.annotations.InjectTestData;
 import io.fd.honeycomb.translate.write.WriteFailedException;
@@ -37,7 +32,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
-import org.mockito.Mock;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev180313.StaticRoutes1;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.Ipv6;
@@ -45,59 +39,63 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicas
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv6.RouteBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv6.RouteKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev180313.routing.control.plane.protocols.control.plane.protocol._static.routes.ipv6.route.NextHopBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.Static;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.next.hop.content.next.hop.options.TableLookupCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.ControlPlaneProtocols;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocol;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocolKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.control.plane.protocol.StaticRoutes;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.types.rev180406.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 
 @RunWith(HoneycombTestRunner.class)
-public class Ipv6RouteCustomizerTest extends WriterCustomizerTest
-        implements RoutingRequestTestHelper, ClassifyTableTestHelper, SchemaContextTestHelper {
-
-    private static final int ROUTE_PROTOCOL_INDEX = 1;
-    public static final Ipv6Prefix IPV_6_PREFIX = new Ipv6Prefix("2001:0db8:0a0b:12f0:0000:0000:0000:0001/64");
+public class Ipv6RouteCustomizerTest extends RouteCustomizerTest {
+
+    private static final TableKey
+            SEC_TABLE_KEY = new TableKey(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6.class,
+            SEC_TABLE_ID);
+    private static final Table
+            IPV6_TABLE = new TableBuilder().setName("VRF-IPV6-4")
+            .setKey(SEC_TABLE_KEY).setTableId(SEC_TABLE_KEY.getTableId())
+            .setAddressFamily(SEC_TABLE_KEY.getAddressFamily()).build();
+    private static final Ipv6Prefix IPV_6_PREFIX = new Ipv6Prefix("2001:0db8:0a0b:12f0:0000:0000:0000:0001/64");
+
+    private static final InstanceIdentifier<Route> ROUTE_IID = CONTROL_PROTOCOL_IID
+            .child(StaticRoutes.class)
+            .augmentation(StaticRoutes1.class)
+            .child(Ipv6.class)
+            .child(Route.class);
+    private static final InstanceIdentifier<Route> ROUTE_INVALID_IID = CONTROL_PROTOCOL_INVALID_IID
+            .child(StaticRoutes.class)
+            .augmentation(StaticRoutes1.class)
+            .child(Ipv6.class)
+            .child(Route.class);
     @Captor
     private ArgumentCaptor<IpAddDelRoute> requestCaptor;
 
-    @Mock
-    private VppClassifierContextManager classifyManager;
-
-    @Mock
-    private MultiNamingContext routeHopContext;
-
-    private NamingContext interfaceContext;
-    private NamingContext routeContext;
-    private NamingContext routingProtocolContext;
     private Ipv6RouteCustomizer customizer;
-
-    private InstanceIdentifier<Route> validId;
     private Ipv6RouteNamesFactory namesFactory;
 
     @Override
     protected void setUpTest() throws Exception {
-        interfaceContext = new NamingContext("interface", "interface-context");
-        routeContext = new NamingContext("interface", "interface-context");
-        routingProtocolContext = new NamingContext("routing-protocol", "routing-protocol-context");
-        customizer =
-                new Ipv6RouteCustomizer(api, interfaceContext, routeContext, routingProtocolContext, routeHopContext,
-                        classifyManager);
-
-        validId = InstanceIdentifier.create(ControlPlaneProtocols.class)
-                .child(ControlPlaneProtocol.class, new ControlPlaneProtocolKey(ROUTE_PROTOCOL_NAME, Static.class))
-                .child(StaticRoutes.class)
-                .augmentation(StaticRoutes1.class)
-                .child(Ipv6.class)
-                .child(Route.class);
-
+        super.setUpTest();
+        customizer = new Ipv6RouteCustomizer(api, interfaceContext, routingProtocolContext, routingProtocolContext,
+                routeHopContext, classifyManager);
         namesFactory = new Ipv6RouteNamesFactory(interfaceContext, routingProtocolContext);
 
-        defineMapping(mappingContext, INTERFACE_NAME, INTERFACE_INDEX, "interface-context");
-        addMapping(classifyManager, CLASSIFY_TABLE_NAME, CLASSIFY_TABLE_INDEX, mappingContext);
-        defineMapping(mappingContext, ROUTE_PROTOCOL_NAME, ROUTE_PROTOCOL_INDEX, "routing-protocol-context");
+        KeyedInstanceIdentifier<Table, TableKey> secondaryFibIid =
+                FibManagementIIds.FM_FIB_TABLES.child(Table.class, SEC_TABLE_KEY);
+        when(writeContext.readAfter(secondaryFibIid)).thenReturn(Optional.of(IPV6_TABLE));
+    }
+
+    @Test(expected = WriteFailedException.class)
+    public void testWriteSingleInvalidHop(
+            @InjectTestData(resourcePath = "/ipv6/simplehop/simpleHopRouteWithClassifier.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
+            throws WriteFailedException {
+        whenAddRouteThenSuccess(api);
+        customizer.writeCurrentAttributes(ROUTE_INVALID_IID, getIpv6RouteWithId(route, IPV_6_PREFIX), writeContext);
+        verifyInvocation(0, ImmutableList.of(), api, requestCaptor);
     }
 
     @Test
@@ -105,11 +103,11 @@ public class Ipv6RouteCustomizerTest extends WriterCustomizerTest
             @InjectTestData(resourcePath = "/ipv6/simplehop/simpleHopRouteWithClassifier.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
             throws WriteFailedException {
         whenAddRouteThenSuccess(api);
-        customizer.writeCurrentAttributes(validId, getIpv6RouteWithId(route, IPV_6_PREFIX), writeContext);
+        customizer.writeCurrentAttributes(ROUTE_IID, getIpv6RouteWithId(route, IPV_6_PREFIX), writeContext);
         verifyInvocation(1, ImmutableList
                 .of(desiredFlaglessResult(1, 1, 0, Ipv6RouteData.FIRST_ADDRESS_AS_ARRAY, 64,
-                        Ipv6RouteData.SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 0, ROUTE_PROTOCOL_INDEX,
-                    0, CLASSIFY_TABLE_INDEX, 1)), api, requestCaptor);
+                        Ipv6RouteData.SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 0, TABLE_ID.intValue(),
+                        0, CLASSIFY_TABLE_INDEX, 1)), api, requestCaptor);
     }
 
     //TODO - https://jira.fd.io/browse/HONEYCOMB-396
@@ -120,14 +118,16 @@ public class Ipv6RouteCustomizerTest extends WriterCustomizerTest
                 .setDestinationPrefix(IPV_6_PREFIX)
                 .setNextHop(new NextHopBuilder().setNextHopOptions(new TableLookupCaseBuilder()
                         .setSecondaryVrf(new VniReference(4L))
+                        .setAddressFamily(
+                                org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6.class)
                         .build()).build())
                 .build();
         whenAddRouteThenSuccess(api);
         noMappingDefined(mappingContext, namesFactory.uniqueRouteName(ROUTE_PROTOCOL_NAME, route), "route-context");
-        customizer.writeCurrentAttributes(validId, route, writeContext);
+        customizer.writeCurrentAttributes(ROUTE_IID, route, writeContext);
         verifyInvocation(1, ImmutableList
                         .of(desiredFlaglessResult(1, 1, 0, Ipv6RouteData.FIRST_ADDRESS_AS_ARRAY, 64,
-                                new byte[4], ~0, 0, ROUTE_PROTOCOL_INDEX, 4,
+                                new byte[4], ~0, 0, TABLE_ID.intValue(), 4,
                                 0, 0)),
                 api, requestCaptor);
     }
@@ -137,21 +137,21 @@ public class Ipv6RouteCustomizerTest extends WriterCustomizerTest
             @InjectTestData(resourcePath = "/ipv6/multihop/multiHopRouteWithClassifier.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
             throws WriteFailedException {
         whenAddRouteThenSuccess(api);
-        customizer.writeCurrentAttributes(validId, getIpv6RouteWithId(route, IPV_6_PREFIX), writeContext);
+        customizer.writeCurrentAttributes(ROUTE_IID, getIpv6RouteWithId(route, IPV_6_PREFIX), writeContext);
         verifyInvocation(2,
                 ImmutableList.of(
                         desiredFlaglessResult(1, 1, 1, Ipv6RouteData.FIRST_ADDRESS_AS_ARRAY, 64,
-                                Ipv6RouteData.SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 2, ROUTE_PROTOCOL_INDEX, 0,
+                                Ipv6RouteData.SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 2, TABLE_ID.intValue(), 0,
                                 CLASSIFY_TABLE_INDEX, 1),
                         desiredFlaglessResult(1, 1, 1, Ipv6RouteData.FIRST_ADDRESS_AS_ARRAY, 64,
-                                Ipv6RouteData.SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 2, ROUTE_PROTOCOL_INDEX, 0,
+                                Ipv6RouteData.SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 2, TABLE_ID.intValue(), 0,
                                 CLASSIFY_TABLE_INDEX, 1)), api,
                 requestCaptor);
     }
 
     @Test(expected = UnsupportedOperationException.class)
     public void testUpdate() throws WriteFailedException {
-        customizer.updateCurrentAttributes(validId, Ipv6RouteData.IPV6_ROUTE_WITH_CLASSIFIER_BLACKHOLE_HOP,
+        customizer.updateCurrentAttributes(ROUTE_IID, Ipv6RouteData.IPV6_ROUTE_WITH_CLASSIFIER_BLACKHOLE_HOP,
                 Ipv6RouteData.IPV6_ROUTE_WITH_CLASSIFIER_RECEIVE_HOP, writeContext);
     }
 
@@ -160,11 +160,11 @@ public class Ipv6RouteCustomizerTest extends WriterCustomizerTest
             @InjectTestData(resourcePath = "/ipv6/specialhop/specialHopRouteBlackhole.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
             throws WriteFailedException {
         whenAddRouteThenSuccess(api);
-        customizer.deleteCurrentAttributes(validId, getIpv6RouteWithId(route, IPV_6_PREFIX),
+        customizer.deleteCurrentAttributes(ROUTE_IID, getIpv6RouteWithId(route, IPV_6_PREFIX),
                 writeContext);
         verifyInvocation(1, ImmutableList
                         .of(desiredSpecialResult(0, 1, Ipv6RouteData.FIRST_ADDRESS_AS_ARRAY, 64,
-                                                 1, 0, 0, 0, ROUTE_PROTOCOL_INDEX, 0)),
+                                1, 0, 0, 0, TABLE_ID.intValue(), 0)),
                          api, requestCaptor);
     }
 
@@ -173,7 +173,7 @@ public class Ipv6RouteCustomizerTest extends WriterCustomizerTest
             @InjectTestData(resourcePath = "/ipv6/simplehop/simpleHopRouteWithClassifier.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
             throws WriteFailedException {
         whenAddRouteThenSuccess(api);
-        customizer.deleteCurrentAttributes(validId, getIpv6RouteWithId(route, IPV_6_PREFIX), writeContext);
+        customizer.deleteCurrentAttributes(ROUTE_IID, getIpv6RouteWithId(route, IPV_6_PREFIX), writeContext);
         verifyInvocation(1, ImmutableList
                 .of(desiredFlaglessResult(0, 1, 0, Ipv6RouteData.FIRST_ADDRESS_AS_ARRAY, 64,
                         Ipv6RouteData.SECOND_ADDRESS_AS_ARRAY, INTERFACE_INDEX, 0, 1,
@@ -185,7 +185,7 @@ public class Ipv6RouteCustomizerTest extends WriterCustomizerTest
             @InjectTestData(resourcePath = "/ipv6/multihop/multiHopRouteWithClassifier.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
             throws WriteFailedException {
         whenAddRouteThenSuccess(api);
-        customizer.deleteCurrentAttributes(validId, getIpv6RouteWithId(route, IPV_6_PREFIX), writeContext);
+        customizer.deleteCurrentAttributes(ROUTE_IID, getIpv6RouteWithId(route, IPV_6_PREFIX), writeContext);
         verifyInvocation(2,
                 ImmutableList.of(
                         desiredFlaglessResult(0, 1, 1, Ipv6RouteData.FIRST_ADDRESS_AS_ARRAY, 64,
@@ -202,11 +202,11 @@ public class Ipv6RouteCustomizerTest extends WriterCustomizerTest
             @InjectTestData(resourcePath = "/ipv6/specialhop/specialHopRouteBlackhole.json", id = STATIC_ROUTE_PATH) StaticRoutes route)
             throws WriteFailedException {
         whenAddRouteThenSuccess(api);
-        customizer.writeCurrentAttributes(validId, getIpv6RouteWithId(route, IPV_6_PREFIX),
+        customizer.writeCurrentAttributes(ROUTE_IID, getIpv6RouteWithId(route, IPV_6_PREFIX),
                 writeContext);
         verifyInvocation(1, ImmutableList
                         .of(desiredSpecialResult(1, 1, Ipv6RouteData.FIRST_ADDRESS_AS_ARRAY, 64,
-                                                 1, 0, 0, 0, ROUTE_PROTOCOL_INDEX, 0)),
+                                1, 0, 0, 0, TABLE_ID.intValue(), 0)),
                          api, requestCaptor);
     }
 }
diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/RouteCustomizerTest.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/RouteCustomizerTest.java
new file mode 100644 (file)
index 0000000..ad1613f
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package io.fd.hc2vpp.routing.write;
+
+import static io.fd.hc2vpp.routing.helpers.InterfaceTestHelper.INTERFACE_INDEX;
+import static io.fd.hc2vpp.routing.helpers.InterfaceTestHelper.INTERFACE_NAME;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
+import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.fib.management.FibManagementIIds;
+import io.fd.hc2vpp.routing.helpers.ClassifyTableTestHelper;
+import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper;
+import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper;
+import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.Static;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.ControlPlaneProtocols;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocol;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocolBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.routing.control.plane.protocols.ControlPlaneProtocolKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.RoutingProtocolVppAttr;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.RoutingProtocolVppAttrBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.routing.control.plane.protocols.control.plane.protocol.VppProtocolAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.fib.tables.TableKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+abstract class RouteCustomizerTest extends WriterCustomizerTest implements RoutingRequestTestHelper,
+        ClassifyTableTestHelper, SchemaContextTestHelper {
+    static final Long TABLE_ID = 1L;
+    static final Long INVALID_TABLE_ID = 3L;
+    static final String ROUTE_PROTOCOL_INVALID_NAME = "tst-protocol-3";
+    static final VniReference SEC_TABLE_ID = new VniReference(4L);
+    private static final TableKey IPV4_TABLE_KEY = new TableKey(Ipv4.class, new VniReference(TABLE_ID));
+    private static final TableKey IPV6_TABLE_KEY = new TableKey(Ipv6.class, new VniReference(TABLE_ID));
+    private static final TableKey INVALID_IPV4_TABLE_KEY = new TableKey(Ipv4.class, new VniReference(INVALID_TABLE_ID));
+    private static final TableKey INVALID_IPV6_TABLE_KEY = new TableKey(Ipv6.class, new VniReference(INVALID_TABLE_ID));
+    private static final InstanceIdentifier<Table> TABLE_V4_IID =
+            FibManagementIIds.FM_FIB_TABLES.child(Table.class, IPV4_TABLE_KEY);
+    private static final InstanceIdentifier<Table> TABLE_V6_IID =
+            FibManagementIIds.FM_FIB_TABLES.child(Table.class, IPV6_TABLE_KEY);
+    private static final InstanceIdentifier<Table> INVALID_TABLE_V4_IID =
+            FibManagementIIds.FM_FIB_TABLES.child(Table.class, INVALID_IPV4_TABLE_KEY);
+    private static final InstanceIdentifier<Table> INVALID_TABLE_V6_IID =
+            FibManagementIIds.FM_FIB_TABLES.child(Table.class, INVALID_IPV6_TABLE_KEY);
+    private static final ControlPlaneProtocolKey
+            CONTROL_PLANE_PROTOCOL_KEY = new ControlPlaneProtocolKey(ROUTE_PROTOCOL_NAME, Static.class);
+    static final KeyedInstanceIdentifier<ControlPlaneProtocol, ControlPlaneProtocolKey>
+            CONTROL_PROTOCOL_IID = InstanceIdentifier.create(ControlPlaneProtocols.class)
+            .child(ControlPlaneProtocol.class, CONTROL_PLANE_PROTOCOL_KEY);
+    private static final ControlPlaneProtocolKey
+            CONTROL_PLANE_PROTOCOL_INVALID_KEY = new ControlPlaneProtocolKey(ROUTE_PROTOCOL_INVALID_NAME, Static.class);
+    static final KeyedInstanceIdentifier<ControlPlaneProtocol, ControlPlaneProtocolKey>
+            CONTROL_PROTOCOL_INVALID_IID = InstanceIdentifier.create(ControlPlaneProtocols.class)
+            .child(ControlPlaneProtocol.class, CONTROL_PLANE_PROTOCOL_INVALID_KEY);
+
+    @Mock
+    VppClassifierContextManager classifyManager;
+
+    @Mock
+    MultiNamingContext routeHopContext;
+
+    NamingContext routingProtocolContext;
+    NamingContext interfaceContext;
+
+    @Override
+    protected void setUpTest() throws Exception {
+        interfaceContext = new NamingContext("interface", "interface-context");
+        routingProtocolContext = new NamingContext("routing-protocol", "routing-protocol-context");
+
+        defineMapping(mappingContext, INTERFACE_NAME, INTERFACE_INDEX, "interface-context");
+        defineMapping(mappingContext, ROUTE_PROTOCOL_NAME, TABLE_ID.intValue(), "routing-protocol-context");
+        defineMapping(mappingContext, ROUTE_PROTOCOL_INVALID_NAME, INVALID_TABLE_ID.intValue(),
+                "routing-protocol-context");
+        addMapping(classifyManager, CLASSIFY_TABLE_NAME, CLASSIFY_TABLE_INDEX, mappingContext);
+        whenAddRouteThenSuccess(api);
+
+        when(writeContext.readAfter(CONTROL_PROTOCOL_IID)).thenReturn(Optional.of(new ControlPlaneProtocolBuilder()
+                .setKey(CONTROL_PLANE_PROTOCOL_KEY).setName(ROUTE_PROTOCOL_NAME).setType(Static.class)
+                .addAugmentation(RoutingProtocolVppAttr.class, new RoutingProtocolVppAttrBuilder()
+                        .setVppProtocolAttributes(new VppProtocolAttributesBuilder()
+                                .setPrimaryVrf(new VniReference(TABLE_ID))
+                                .build()).build())
+                .build()));
+
+        when(writeContext.readAfter(CONTROL_PROTOCOL_INVALID_IID)).thenReturn(Optional.of(
+                new ControlPlaneProtocolBuilder().setKey(CONTROL_PLANE_PROTOCOL_INVALID_KEY)
+                        .setName(ROUTE_PROTOCOL_INVALID_NAME).setType(Static.class)
+                        .addAugmentation(RoutingProtocolVppAttr.class, new RoutingProtocolVppAttrBuilder()
+                                .setVppProtocolAttributes(new VppProtocolAttributesBuilder()
+                                        .setPrimaryVrf(new VniReference(INVALID_TABLE_ID)).build()).build())
+                        .build()));
+
+        when(writeContext.readAfter(TABLE_V4_IID)).thenReturn(Optional.of(
+                new TableBuilder().setKey(IPV4_TABLE_KEY).setAddressFamily(Ipv4.class)
+                        .setTableId(IPV4_TABLE_KEY.getTableId()).build()));
+        when(writeContext.readAfter(TABLE_V6_IID)).thenReturn(Optional.of(
+                new TableBuilder().setKey(IPV6_TABLE_KEY).setAddressFamily(Ipv6.class)
+                        .setTableId(IPV6_TABLE_KEY.getTableId()).build()));
+        when(writeContext.readAfter(INVALID_TABLE_V4_IID)).thenReturn(Optional.absent());
+        when(writeContext.readAfter(INVALID_TABLE_V6_IID)).thenReturn(Optional.absent());
+
+    }
+}
diff --git a/routing/routing-impl/src/test/resources/init/config-data.json b/routing/routing-impl/src/test/resources/init/config-data.json
deleted file mode 100644 (file)
index 1f7a6a2..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-{
-  "routing": {
-    "routing-instance": {
-      "name": "routing-3",
-      "router-id": "192.168.2.1",
-      "routing-protocols": {
-        "routing-protocol": [
-          {
-            "name": "test-routing-protocol",
-            "type": "static",
-            "vpp-protocol-attributes": {
-              "primary-vrf": "1"
-            },
-            "static-routes": {
-              "ipv4": {
-                "route": [
-                  {
-                    "id": 1,
-                    "destination-prefix": "192.168.2.3/32",
-                    "next-hop": "192.168.2.8",
-                    "outgoing-interface": "local0"
-                  },
-                  {
-                    "id": 2,
-                    "destination-prefix": "192.168.2.4/32",
-                    "next-hop-list": {
-                      "next-hop": [
-                        {
-                          "id": "1",
-                          "address": "192.168.2.5",
-                          "outgoing-interface": "local0",
-                          "weight": "1"
-                        },
-                        {
-                          "id": "2",
-                          "address": "192.168.2.6",
-                          "outgoing-interface": "local0",
-                          "weight": "2"
-                        }
-                      ]
-                    }
-                  },
-                  {
-                    "id": 3,
-                    "destination-prefix": "192.168.2.5/32",
-                    "special-next-hop": "receive"
-                  },
-                  {
-                    "id": 4,
-                    "destination-prefix": "192.168.2.6/32",
-                    "table-lookup-params": {
-                      "secondary-vrf": 4
-                    }
-                  }
-                ]
-              },
-              "ipv6": {
-                "route": [
-                  {
-                    "id": 1,
-                    "destination-prefix": "2001:0db8:0a0b:12f0:0000:0000:0000:0001/64",
-                    "next-hop": "2001:0db8:0a0b:12f0:0000:0000:0000:0002",
-                    "outgoing-interface": "GigabitEthernet0/8/0"
-                  },
-                  {
-                    "id": 2,
-                    "destination-prefix": "2001:0db8:0a0b:12f0:0000:0000:0000:0008/64",
-                    "next-hop-list": {
-                      "next-hop": [
-                        {
-                          "id": "1",
-                          "address": "2001:0db8:0a0b:12f0:0000:0000:0000:0003",
-                          "outgoing-interface": "GigabitEthernet0/8/0",
-                          "weight": "1"
-                        },
-                        {
-                          "id": "2",
-                          "address": "2001:0db8:0a0b:12f0:0000:0000:0000:0004",
-                          "outgoing-interface": "GigabitEthernet0/8/0",
-                          "weight": "2"
-                        },
-                        {
-                          "id": "3",
-                          "address": "2001:0db8:0a0b:12f0:0000:0000:0000:0005",
-                          "outgoing-interface": "GigabitEthernet0/8/0",
-                          "weight": "3"
-                        }
-                      ]
-                    }
-                  },
-                  {
-                    "id": 3,
-                    "destination-prefix": "2001:0db8:0a0b:12f0:0000:0000:0000:0005/32",
-                    "special-next-hop": "receive"
-                  },
-                  {
-                    "id": 4,
-                    "destination-prefix": "2001:0db8:0a0b:12f0:0000:0000:0000:0006/32",
-                    "table-lookup-params": {
-                      "secondary-vrf": 2
-                    }
-                  }
-                ]
-              }
-            }
-          }
-        ]
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/routing/routing-impl/src/test/resources/init/state-data.json b/routing/routing-impl/src/test/resources/init/state-data.json
deleted file mode 100644 (file)
index fb4fac2..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-{
-  "routing-state": {
-    "routing-instance": {
-      "name": "routing-3",
-      "router-id": "192.168.2.1",
-      "routing-protocols": {
-        "routing-protocol": [
-          {
-            "name": "test-routing-protocol",
-            "type": "static",
-            "vpp-protocol-state-attributes": {
-              "primary-vrf": "1"
-            },
-            "static-routes": {
-              "ipv4": {
-                "route": [
-                  {
-                    "id": 1,
-                    "destination-prefix": "192.168.2.3/32",
-                    "next-hop": "192.168.2.8",
-                    "outgoing-interface": "local0"
-                  },
-                  {
-                    "id": 2,
-                    "destination-prefix": "192.168.2.4/32",
-                    "next-hop-list": {
-                      "next-hop": [
-                        {
-                          "id": "1",
-                          "address": "192.168.2.5",
-                          "outgoing-interface": "local0",
-                          "weight": "1"
-                        },
-                        {
-                          "id": "2",
-                          "address": "192.168.2.6",
-                          "outgoing-interface": "local0",
-                          "weight": "2"
-                        }
-                      ]
-                    }
-                  },
-                  {
-                    "id": 3,
-                    "destination-prefix": "192.168.2.5/32",
-                    "special-next-hop": "receive"
-                  },
-                  {
-                    "id": 4,
-                    "destination-prefix": "192.168.2.6/32",
-                    "table-lookup-params": {
-                      "secondary-vrf": 4
-                    }
-                  }
-                ]
-              },
-              "ipv6": {
-                "route": [
-                  {
-                    "id": 1,
-                    "destination-prefix": "2001:0db8:0a0b:12f0:0000:0000:0000:0001/64",
-                    "next-hop": "2001:0db8:0a0b:12f0:0000:0000:0000:0002",
-                    "outgoing-interface": "GigabitEthernet0/8/0"
-                  },
-                  {
-                    "id": 2,
-                    "destination-prefix": "2001:0db8:0a0b:12f0:0000:0000:0000:0008/64",
-                    "next-hop-list": {
-                      "next-hop": [
-                        {
-                          "id": "1",
-                          "address": "2001:0db8:0a0b:12f0:0000:0000:0000:0003",
-                          "outgoing-interface": "GigabitEthernet0/8/0",
-                          "weight": "1"
-                        },
-                        {
-                          "id": "2",
-                          "address": "2001:0db8:0a0b:12f0:0000:0000:0000:0004",
-                          "outgoing-interface": "GigabitEthernet0/8/0",
-                          "weight": "2"
-                        },
-                        {
-                          "id": "3",
-                          "address": "2001:0db8:0a0b:12f0:0000:0000:0000:0005",
-                          "outgoing-interface": "GigabitEthernet0/8/0",
-                          "weight": "3"
-                        }
-                      ]
-                    }
-                  },
-                  {
-                    "id": 3,
-                    "destination-prefix": "2001:0db8:0a0b:12f0:0000:0000:0000:0005/32",
-                    "special-next-hop": "receive"
-                  },
-                  {
-                    "id": 4,
-                    "destination-prefix": "2001:0db8:0a0b:12f0:0000:0000:0000:0006/32",
-                    "table-lookup-params": {
-                      "secondary-vrf": 2
-                    }
-                  }
-                ]
-              }
-            }
-          }
-        ]
-      }
-    }
-  }
-}
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index ee2da5d..3132e5f
@@ -1,12 +1,90 @@
 {
        "info": {
-               "_postman_id": "ad50e1ac-df20-4667-82cf-41321601c1f9",
+               "_postman_id": "ea03e25f-2a73-4fc1-a806-31b6f862ecc5",
                "name": "Routing",
                "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
        },
        "item": [
                {
-                       "name": "IPv4",
+                       "name": "1. Add FIB tables",
+                       "description": "",
+                       "item": [
+                               {
+                                       "name": "write FIB tables",
+                                       "request": {
+                                               "method": "PUT",
+                                               "header": [
+                                                       {
+                                                               "key": "Authorization",
+                                                               "value": "Basic YWRtaW46YWRtaW4="
+                                                       },
+                                                       {
+                                                               "key": "Content-Type",
+                                                               "value": "application/json"
+                                                       }
+                                               ],
+                                               "body": {
+                                                       "mode": "raw",
+                                                       "raw": "{\n    \"fib-tables\": {\n        \"table\": [\n            {\n                \"table-id\": 0,\n                \"address-family\": \"vpp-fib-table-management:ipv4\",\n                \"name\": \"ipv4-VRF:0\"\n            },\n            {\n                \"table-id\": 0,\n                \"address-family\": \"vpp-fib-table-management:ipv6\",\n                \"name\": \"ipv6-VRF:0\"\n            },\n            {\n                \"table-id\": 1,\n                \"address-family\": \"vpp-fib-table-management:ipv4\",\n                \"name\": \"ipv4-VRF:1\"\n            },\n            {\n                \"table-id\": 1,\n                \"address-family\": \"vpp-fib-table-management:ipv6\",\n                \"name\": \"ipv6-VRF:1\"\n            }\n        ]\n    }\n}"
+                                               },
+                                               "url": {
+                                                       "raw": "http://localhost:8183/restconf/config/vpp-fib-table-management:fib-table-management/fib-tables/",
+                                                       "protocol": "http",
+                                                       "host": [
+                                                               "localhost"
+                                                       ],
+                                                       "port": "8183",
+                                                       "path": [
+                                                               "restconf",
+                                                               "config",
+                                                               "vpp-fib-table-management:fib-table-management",
+                                                               "fib-tables",
+                                                               ""
+                                                       ]
+                                               }
+                                       },
+                                       "response": []
+                               },
+                               {
+                                       "name": "read all FIB tables - operational",
+                                       "request": {
+                                               "method": "GET",
+                                               "header": [
+                                                       {
+                                                               "key": "Authorization",
+                                                               "value": "Basic YWRtaW46YWRtaW4="
+                                                       },
+                                                       {
+                                                               "key": "Content-Type",
+                                                               "value": "application/json"
+                                                       }
+                                               ],
+                                               "body": {
+                                                       "mode": "raw",
+                                                       "raw": ""
+                                               },
+                                               "url": {
+                                                       "raw": "http://localhost:8183/restconf/operational/vpp-fib-table-management:fib-table-management/fib-tables/",
+                                                       "protocol": "http",
+                                                       "host": [
+                                                               "localhost"
+                                                       ],
+                                                       "port": "8183",
+                                                       "path": [
+                                                               "restconf",
+                                                               "operational",
+                                                               "vpp-fib-table-management:fib-table-management",
+                                                               "fib-tables",
+                                                               ""
+                                                       ]
+                                               }
+                                       },
+                                       "response": []
+                               }
+                       ]
+               },
+               {
+                       "name": "2. IPv4",
                        "description": null,
                        "item": [
                                {
                        ]
                },
                {
-                       "name": "IPv6",
+                       "name": "3. IPv6",
                        "description": null,
                        "item": [
                                {