diff options
Diffstat (limited to 'routing')
11 files changed, 497 insertions, 7 deletions
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/RoutingModule.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/RoutingModule.java index 8a109aece..6badcab29 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/RoutingModule.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/RoutingModule.java @@ -16,15 +16,21 @@ 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 index 000000000..147218564 --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableService.java @@ -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 index 000000000..711b687d8 --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableServiceImpl.java @@ -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 index 000000000..a22120d55 --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/services/FibTableServiceProvider.java @@ -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); + } +} diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizer.java index 0a0fa3e47..c0d5d083b 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizer.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizer.java @@ -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) diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java index 05d6916cb..cd3c4d275 100644 --- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java @@ -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; @@ -63,6 +64,9 @@ public final class RoutingWriterFactory implements WriterFactory, Ipv4RoutingNod 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 index 000000000..fefbadefa --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/FibTableRequest.java @@ -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; + } +} diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv4RouteCustomizerTest.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv4RouteCustomizerTest.java index 5e319e370..0ba1fe576 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv4RouteCustomizerTest.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv4RouteCustomizerTest.java @@ -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 +} diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv6RouteCustomizerTest.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv6RouteCustomizerTest.java index 503c01914..81dae7bfd 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv6RouteCustomizerTest.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/read/Ipv6RouteCustomizerTest.java @@ -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 index 000000000..2edd70ce5 --- /dev/null +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/services/FibTableServiceImplTest.java @@ -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); + } +} diff --git a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizerTest.java b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizerTest.java index fa25520ca..b4cf64ead 100644 --- a/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizerTest.java +++ b/routing/routing-impl/src/test/java/io/fd/hc2vpp/routing/write/ControlPlaneProtocolCustomizerTest.java @@ -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 |