HC2VPP-317 - Add FibService and FibTableService 78/12378/6
authorMichal Cmarada <[email protected]>
Thu, 10 May 2018 08:14:07 +0000 (10:14 +0200)
committerMichal Cmarada <[email protected]>
Thu, 10 May 2018 08:14:07 +0000 (10:14 +0200)
VPP doesn`t support auto create for Fib tables anymore,
when adding a new route.
Adding FibService to check if table exists and
FibTableService to add or delete ipv4/6 fib tables.

Note: Need to implement full support for Fib Table management later.

Change-Id: I15bd1b62357ab24a5eac970113bfcd2a52d29491
Signed-off-by: Michal Cmarada <[email protected]>
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/RoutingModule.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableService.java [new file with mode: 0644]
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableServiceImpl.java [new file with mode: 0644]
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableServiceProvider.java [new file with mode: 0644]
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizer.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/FibTableRequest.java [new file with mode: 0644]
routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv4RouteCustomizerTest.java
routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv6RouteCustomizerTest.java
routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/services/FibTableServiceImplTest.java [new file with mode: 0644]
routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizerTest.java

index 8a109ae..6badcab 100644 (file)
 
 package io.fd.hc2vpp.routing;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.inject.AbstractModule;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
 import com.google.inject.name.Names;
 import io.fd.hc2vpp.common.translate.util.MultiNamingContext;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.routing.read.RoutingReaderFactory;
+import io.fd.hc2vpp.routing.services.FibTableService;
+import io.fd.hc2vpp.routing.services.FibTableServiceProvider;
 import io.fd.hc2vpp.routing.write.RoutingWriterFactory;
 import io.fd.honeycomb.translate.read.ReaderFactory;
 import io.fd.honeycomb.translate.write.WriterFactory;
+import javax.annotation.Nonnull;
 import net.jmob.guice.conf.core.ConfigurationModule;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,12 +41,23 @@ import org.slf4j.LoggerFactory;
 public class RoutingModule extends AbstractModule {
 
     private static final Logger LOG = LoggerFactory.getLogger(RoutingModule.class);
+    private final Class<? extends Provider<FibTableService>> fibTableServiceProvider;
+
+    public RoutingModule() {
+        this(FibTableServiceProvider.class);
+    }
+
+    @VisibleForTesting
+    protected RoutingModule(@Nonnull final Class<? extends Provider<FibTableService>> fibTableServiceProvider) {
+        this.fibTableServiceProvider = fibTableServiceProvider;
+    }
 
     @Override
     protected void configure() {
         LOG.info("Starting initialization");
         // requests injection of properties
         install(ConfigurationModule.create());
+        bind(FibTableService.class).toProvider(fibTableServiceProvider).in(Singleton.class);
         requestInjection(RoutingConfiguration.class);
 
         bind(NamingContext.class)
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableService.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableService.java
new file mode 100644 (file)
index 0000000..1472185
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.services;
+
+import static java.lang.String.format;
+
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface FibTableService {
+
+    /**
+     * Checks whether FIB table with provided index exist in VPP
+     *
+     * @throws ReadFailedException                           if there was an error while reading fib tables
+     * @throws FibTableService.FibTableDoesNotExistException if requested index does not exist
+     */
+    void checkTableExist(@Nonnegative final int index, @Nonnull final ModificationCache cache)
+            throws ReadFailedException, FibTableService.FibTableDoesNotExistException;
+
+    /**
+     * Writes FIB table in VPP
+     *
+     * @param identifier id of currently processed data
+     * @param tableId    table Id to be written in VPP
+     * @param tableName  name of the FIB table that will be added
+     * @param isIpv6     true if adding IPv6 FIB table, false if adding IPv4 table
+     * @throws WriteFailedException if there was an error while writing FIB tables
+     */
+    void write(InstanceIdentifier<?> identifier, @Nonnegative int tableId, @Nonnull String tableName, boolean isIpv6)
+            throws WriteFailedException;
+
+    class FibTableDoesNotExistException extends Exception {
+
+        public FibTableDoesNotExistException(final int index) {
+            super(format("Fib table with index %s does not exist", index));
+        }
+    }
+}
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableServiceImpl.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableServiceImpl.java
new file mode 100644 (file)
index 0000000..711b687
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.services;
+
+import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS;
+
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.routing.RoutingIIds;
+import io.fd.hc2vpp.routing.write.factory.FibTableRequest;
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.Ip6FibDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.Ip6FibDump;
+import io.fd.vpp.jvpp.core.dto.IpFibDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.IpFibDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
+import java.util.stream.Stream;
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+// Todo HC2VPP-317: FibTableService was created as a temporary workaround to write Fib tables in VPP.
+// We need to implement proper support for Fib table management.
+public class FibTableServiceImpl extends FutureJVppCustomizer implements FibTableService, JvppReplyConsumer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FibTableServiceImpl.class);
+    private final DumpCacheManager<IpFibDetailsReplyDump, Void> v4DumpManager;
+    private final DumpCacheManager<Ip6FibDetailsReplyDump, Void> v6DumpManager;
+    private ModificationCache modificationCache;
+
+    public FibTableServiceImpl(@Nonnull FutureJVppCore futureJVppCore, ModificationCache modificationCache) {
+        super(futureJVppCore);
+        this.modificationCache = modificationCache;
+
+        v4DumpManager = new DumpCacheManager.DumpCacheManagerBuilder<IpFibDetailsReplyDump, Void>()
+                .acceptOnly(IpFibDetailsReplyDump.class)
+                .withExecutor((identifier, params) -> getReplyForRead(
+                        futureJVppCore.ipFibDump(new IpFibDump()).toCompletableFuture(), identifier))
+                .build();
+        v6DumpManager = new DumpCacheManager.DumpCacheManagerBuilder<Ip6FibDetailsReplyDump, Void>()
+                .acceptOnly(Ip6FibDetailsReplyDump.class)
+                .withExecutor((identifier, params) -> getReplyForRead(
+                        futureJVppCore.ip6FibDump(new Ip6FibDump()).toCompletableFuture(), identifier))
+                .build();
+    }
+
+    @Override
+    public void write(InstanceIdentifier<?> identifier, @Nonnegative int tableId, @Nonnull String tableName,
+                      boolean isIpv6) throws WriteFailedException {
+        //register fib table in VPP
+        FibTableRequest fibTableRequest = new FibTableRequest(getFutureJVpp(), this, modificationCache);
+        fibTableRequest.setFibName(tableName);
+        fibTableRequest.setIpv6(isIpv6);
+        fibTableRequest.setFibTable(tableId);
+        fibTableRequest.checkValid();
+        try {
+            fibTableRequest.write(identifier);
+            LOG.debug("Fib table written successfully. table-name: {}, table-id: {}, request: {}", tableName, tableId,
+                    fibTableRequest);
+        } catch (WriteFailedException e) {
+            LOG.warn("Fib table write failed. request: {}", fibTableRequest);
+            throw new WriteFailedException(identifier, "Failed to write fib table to VPP.", e);
+        }
+    }
+
+    @Override
+    public void checkTableExist(@Nonnegative final int index,
+                                @Nonnull final ModificationCache cache)
+            throws ReadFailedException, FibTableService.FibTableDoesNotExistException {
+
+        if (Stream.concat(dumpV4FibTableIdsStream(cache), dumpV6FibTableIdsStream(cache))
+                .noneMatch(id -> id == index)) {
+            throw new FibTableService.FibTableDoesNotExistException(index);
+        }
+    }
+
+    private Stream<Integer> dumpV6FibTableIdsStream(final ModificationCache cache) throws ReadFailedException {
+        return v6DumpManager.getDump(RoutingIIds.ROUTING, cache, NO_PARAMS)
+                .toJavaUtil()
+                .map(ip6FibDetailsReplyDump -> ip6FibDetailsReplyDump.ip6FibDetails)
+                .orElse(Collections.emptyList())
+                .stream()
+                .map(ip6FibDetails -> ip6FibDetails.tableId);
+    }
+
+    private Stream<Integer> dumpV4FibTableIdsStream(final ModificationCache cache) throws ReadFailedException {
+        return v4DumpManager.getDump(RoutingIIds.ROUTING, cache, NO_PARAMS)
+                .toJavaUtil()
+                .map(ipFibDetailsReplyDump -> ipFibDetailsReplyDump.ipFibDetails)
+                .orElse(Collections.emptyList())
+                .stream()
+                .map(ipFibDetails -> ipFibDetails.tableId);
+    }
+}
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableServiceProvider.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableServiceProvider.java
new file mode 100644 (file)
index 0000000..a22120d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.services;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+
+public class FibTableServiceProvider implements Provider<FibTableService> {
+
+    @Inject
+    private
+    FutureJVppCore api;
+
+    @Inject
+    private ModificationCache modificationCache;
+
+    @Override
+    public FibTableService get() {
+        return new FibTableServiceImpl(api, modificationCache);
+    }
+}
index 0a0fa3e..c0d5d08 100644 (file)
@@ -20,7 +20,9 @@ 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.routing.services.FibTableService;
 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;
@@ -30,17 +32,23 @@ 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.ControlPlaneProtocolKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev180319.RoutingProtocolVppAttr;
 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) {
+    ControlPlaneProtocolCustomizer(@Nonnull final NamingContext routingProtocolContext,
+                                   FibTableService fibTableService) {
         this.routingProtocolContext = routingProtocolContext;
+        this.fibTableService = fibTableService;
     }
 
     @Override
@@ -57,8 +65,22 @@ final class ControlPlaneProtocolCustomizer
         // enclosed in synchronized block to prevent change of state after containsName/before addName
         synchronized (routingProtocolContext) {
             if (!routingProtocolContext.containsName(tableId, mappingContext)) {
-                // if not present in mapping,create assignment to table id. This works only with auto-create flag enabled
-                // while using ip_add_del_table
+                // Todo HC2VPP-317: A proper solution for Fib table management should be implemented. This is a
+                // temporary workaround.
+
+                // 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.");
+                    //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)
index 05d6916..cd3c4d2 100644 (file)
@@ -29,6 +29,7 @@ import io.fd.hc2vpp.routing.Ipv4RoutingNodes;
 import io.fd.hc2vpp.routing.Ipv6RoutingNodes;
 import io.fd.hc2vpp.routing.RoutingConfiguration;
 import io.fd.hc2vpp.routing.RoutingIIds;
+import io.fd.hc2vpp.routing.services.FibTableService;
 import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
 import io.fd.honeycomb.translate.impl.write.GenericWriter;
 import io.fd.honeycomb.translate.write.WriterFactory;
@@ -62,6 +63,9 @@ public final class RoutingWriterFactory implements WriterFactory, Ipv4RoutingNod
     @Inject
     private RoutingConfiguration configuration;
 
+    @Inject
+    private FibTableService fibTableService;
+
     @Inject
     @Named("interface-context")
     private NamingContext interfaceContext;
@@ -89,7 +93,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)));
+                new ControlPlaneProtocolCustomizer(routingProtocolContext, fibTableService)));
 
         registry.subtreeAddAfter(ipv4RoutingHandledChildren(RoutingIIds.RT_CPS_CP_SR_SRV4_IPV4_RT_PARENT),
                                  new GenericWriter<>(RoutingIIds.RT_CPS_CP_SR_SRV4_IPV4_RT,
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/FibTableRequest.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/FibTableRequest.java
new file mode 100644 (file)
index 0000000..fefbade
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.factory;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.AddressTranslator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.routing.services.FibTableService;
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.IpTableAddDel;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FibTableRequest implements AddressTranslator, JvppReplyConsumer {
+
+    private final FibTableService fibTableService;
+    private final ModificationCache modificationCache;
+    private static final Logger LOG = LoggerFactory.getLogger(FibTableRequest.class);
+
+    private final FutureJVppCore api;
+    /**
+     * FIB table Name
+     */
+    private String fibName;
+
+    /**
+     * FIB table id to be installed
+     */
+    private int fibTable;
+
+    /**
+     * Whether to write IPv6 fib table or IPv4
+     */
+    private boolean isIpv6;
+
+    public FibTableRequest(FutureJVppCore api, FibTableService fibTableService, ModificationCache modificationCache) {
+        this.api = api;
+        this.fibTableService = fibTableService;
+        this.modificationCache = modificationCache;
+    }
+
+    public void checkValid() {
+        checkNotNull(getFibName(), "Fib table name not set");
+        checkArgument(!getFibName().isEmpty(), "Fib table name must not be empty");
+    }
+
+    public void delete(InstanceIdentifier<?> identifier) throws WriteFailedException {
+        try {
+            fibTableService.checkTableExist(getFibTable(), modificationCache);
+            IpTableAddDel tableAddDel = new IpTableAddDel();
+            tableAddDel.tableId = getFibTable();
+            tableAddDel.isIpv6 = (booleanToByte(isIpv6()));
+            tableAddDel.isAdd = (booleanToByte(false));
+            tableAddDel.name = getFibName().getBytes();
+            getReplyForWrite(api.ipTableAddDel(tableAddDel).toCompletableFuture(), identifier);
+        } catch (ReadFailedException e) {
+            throw new IllegalArgumentException(e);
+        } catch (FibTableService.FibTableDoesNotExistException e){
+            LOG.debug("Request to delete non existing Fib table");
+        }
+    }
+
+    public void write(InstanceIdentifier<?> identifier) throws WriteFailedException {
+        IpTableAddDel tableAddDel = new IpTableAddDel();
+        try {
+            tableAddDel.tableId = getFibTable();
+            tableAddDel.isIpv6 = (booleanToByte(isIpv6()));
+            tableAddDel.isAdd = (booleanToByte(true));
+            tableAddDel.name = getFibName().getBytes();
+            getReplyForWrite(api.ipTableAddDel(tableAddDel).toCompletableFuture(), identifier);
+        } catch (Exception ex){
+            LOG.error("Error writing fib table. fibTable: {}, api: {}, cache: {}, id: {}", tableAddDel, api,
+                      modificationCache, identifier);
+            throw new WriteFailedException(identifier, ex);
+        }
+    }
+
+    public int getFibTable() {
+        return fibTable;
+    }
+
+    public void setFibTable(int fibTable) {
+        this.fibTable = fibTable;
+    }
+
+    public boolean isIpv6() {
+        return isIpv6;
+    }
+
+    public void setIpv6(boolean ipv6) {
+        isIpv6 = ipv6;
+    }
+
+    public String getFibName() {
+        return fibName;
+    }
+
+    public void setFibName(String fibName) {
+        this.fibName = fibName;
+    }
+}
index 5e319e3..0ba1fe5 100644 (file)
@@ -139,6 +139,7 @@ public class Ipv4RouteCustomizerTest extends ListReaderCustomizerTest<Route, Rou
                 mappingContext)).thenReturn(0);
         when(routeHopContext.getChildIndex(listRouteName, factory.uniqueRouteHopName(listRoute.path[1], mappingContext),
                 mappingContext)).thenReturn(1);
+        when(configuration.getLearnedRouteNamePrefix()).thenReturn("learned-route");
     }
 
     private IpFibDetailsReplyDump replyDump() {
@@ -278,4 +279,4 @@ public class Ipv4RouteCustomizerTest extends ListReaderCustomizerTest<Route, Rou
         return new Ipv4RouteCustomizer(manager, configuration, routeHopContext, interfaceContext,
                                        routesContext, routingProtocolContext);
     }
-}
\ No newline at end of file
+}
index 503c019..81dae7b 100644 (file)
@@ -159,6 +159,7 @@ public class Ipv6RouteCustomizerTest extends ListReaderCustomizerTest<Route, Rou
         when(routeHopContext.getChildIndex(listRouteName, factory.uniqueRouteHopName(listRoute.path[1], mappingContext),
                 mappingContext))
                 .thenReturn(1);
+        when(configuration.getLearnedRouteNamePrefix()).thenReturn("learned-route");
     }
 
     private Ip6FibDetailsReplyDump replyDump() {
@@ -303,4 +304,4 @@ public class Ipv6RouteCustomizerTest extends ListReaderCustomizerTest<Route, Rou
         return new Ipv6RouteCustomizer(manager, configuration, routeHopContext,
                                        interfaceContext, routesContext, routingProtocolContext);
     }
-}
\ No newline at end of file
+}
diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/services/FibTableServiceImplTest.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/services/FibTableServiceImplTest.java
new file mode 100644 (file)
index 0000000..2edd70c
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.services;
+
+import static io.fd.vpp.jvpp.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.inject.Inject;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.routing.RoutingIIds;
+import io.fd.hc2vpp.routing.helpers.RoutingRequestTestHelper;
+import io.fd.hc2vpp.routing.helpers.SchemaContextTestHelper;
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.Ip6FibDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.IpFibDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.IpTableAddDel;
+import io.fd.vpp.jvpp.core.dto.IpTableAddDelReply;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class FibTableServiceImplTest implements RoutingRequestTestHelper, SchemaContextTestHelper {
+
+    private static final int FIB_TABLE_ID = 123456;
+    private static final String FIB_TABLE_NAME = "VRF123456";
+
+    @Inject
+    @Mock
+    private static FutureJVppCore api;
+
+    @Mock
+    private static WriteContext ctx;
+
+    @Mock
+    private ModificationCache modificationCache;
+
+    @Captor
+    private ArgumentCaptor<IpTableAddDel> argumentCaptor;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        when(api.ipTableAddDel(any())).thenReturn(future(new IpTableAddDelReply()));
+        when(api.ipFibDump(any())).thenReturn(future(new IpFibDetailsReplyDump()));
+        when(api.ip6FibDump(any())).thenReturn(future(new Ip6FibDetailsReplyDump()));
+        when(modificationCache.get(any())).thenReturn(null);
+
+    }
+
+    @Test(expected = FibTableService.FibTableDoesNotExistException.class)
+    public void checkTableExistTest() throws ReadFailedException, FibTableService.FibTableDoesNotExistException {
+        FibTableServiceImpl fibService = new FibTableServiceImpl(api, ctx.getModificationCache());
+
+        fibService.checkTableExist(FIB_TABLE_ID, modificationCache);
+    }
+
+    @Test
+    public void writeIpv4Test() throws WriteFailedException {
+        FibTableServiceImpl fibTableService = new FibTableServiceImpl(api, ctx.getModificationCache());
+        fibTableService.write(RoutingIIds.ROUTING, FIB_TABLE_ID, FIB_TABLE_NAME, false);
+
+        verify(api, times(1)).ipTableAddDel(argumentCaptor.capture());
+
+        final IpTableAddDel jvppRequest = argumentCaptor.getValue();
+        assertTableAddDelRequest(jvppRequest, true, false);
+    }
+
+    @Test
+    public void writeIpv6Test() throws WriteFailedException {
+        FibTableServiceImpl fibTableService = new FibTableServiceImpl(api, ctx.getModificationCache());
+        fibTableService.write(RoutingIIds.ROUTING, FIB_TABLE_ID, FIB_TABLE_NAME, true);
+
+        verify(api, times(1)).ipTableAddDel(argumentCaptor.capture());
+
+        final IpTableAddDel jvppRequest = argumentCaptor.getValue();
+        assertTableAddDelRequest(jvppRequest, true, true);
+    }
+
+    private void assertTableAddDelRequest(IpTableAddDel jvppRequest, boolean isAdd, boolean isIpv6) {
+        assertEquals(ByteDataTranslator.INSTANCE.booleanToByte(isAdd), jvppRequest.isAdd);
+        assertEquals(ByteDataTranslator.INSTANCE.booleanToByte(isIpv6), jvppRequest.isIpv6);
+        assertEquals(FIB_TABLE_ID, jvppRequest.tableId);
+        Assert.assertArrayEquals(FIB_TABLE_NAME.getBytes(), jvppRequest.name);
+    }
+}
index fa25520..b4cf64e 100644 (file)
@@ -23,9 +23,11 @@ import static org.junit.Assert.fail;
 
 import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.routing.services.FibTableService;
 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.control.plane.protocols.ControlPlaneProtocol;
@@ -45,6 +47,9 @@ public class ControlPlaneProtocolCustomizerTest extends WriterCustomizerTest {
     private ControlPlaneProtocolCustomizer customizer;
     private NamingContext routingProtocolContext;
 
+    @Mock
+    protected FibTableService fibTableService;
+
     @Before
     public void init() {
         validId = InstanceIdentifier.create(ControlPlaneProtocol.class);
@@ -73,7 +78,7 @@ public class ControlPlaneProtocolCustomizerTest extends WriterCustomizerTest {
                 .build();
 
         routingProtocolContext = new NamingContext("routing-protocol", "routing-protocol-context");
-        customizer = new ControlPlaneProtocolCustomizer(routingProtocolContext);
+        customizer = new ControlPlaneProtocolCustomizer(routingProtocolContext, fibTableService);
     }
 
     @Test