diff options
author | Michal Cmarada <michal.cmarada@pantheon.tech> | 2018-06-08 11:54:53 +0200 |
---|---|---|
committer | Michal Cmarada <michal.cmarada@pantheon.tech> | 2018-06-08 11:54:53 +0200 |
commit | 887fb8a181146390bccb6eaf5caeb0a84659c750 (patch) | |
tree | be6ea451e14ea62894feb837bb1e731260e803da /fib-management/fib-management-impl/src | |
parent | 36f90b9d6f6912303222b9bf26ebb3d87b19aac4 (diff) |
HC2VPP-317 - Implement FIB table management support
changes:
- Added new custom model vpp-fib-table-management
- allows management of IPv4 and IPv6 Fib tables for VPP
Change-Id: I3647dd659dbefabab233eacef666c3835e69320d
Signed-off-by: Michal Cmarada <michal.cmarada@pantheon.tech>
Diffstat (limited to 'fib-management/fib-management-impl/src')
16 files changed, 1217 insertions, 0 deletions
diff --git a/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/FibManagementIIds.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/FibManagementIIds.java new file mode 100644 index 000000000..c79ca2b16 --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/FibManagementIIds.java @@ -0,0 +1,29 @@ +/* + * 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.fib.management; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.FibTableManagement; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.FibTables; +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.yangtools.yang.binding.InstanceIdentifier; + +public class FibManagementIIds { + public static final InstanceIdentifier<FibTableManagement> FIB_MNGMNT = + InstanceIdentifier.create(FibTableManagement.class); + public static final InstanceIdentifier<FibTables> FM_FIB_TABLES = FIB_MNGMNT.child(FibTables.class); + public static final InstanceIdentifier<Table> FM_FTBLS_TABLE = FM_FIB_TABLES.child(Table.class); +} diff --git a/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/FibManagementModule.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/FibManagementModule.java new file mode 100644 index 000000000..462a1e4f6 --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/FibManagementModule.java @@ -0,0 +1,71 @@ +/* + * 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.fib.management; + +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 io.fd.hc2vpp.fib.management.read.FibManagementReaderFactory; +import io.fd.hc2vpp.fib.management.services.FibTableService; +import io.fd.hc2vpp.fib.management.services.FibTableServiceProvider; +import io.fd.hc2vpp.fib.management.write.FibManagementWriterFactory; +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; + +/** + * FibManagementModule class instantiating FIB management plugin components. + */ +public class FibManagementModule extends AbstractModule { + + private static final Logger LOG = LoggerFactory.getLogger(FibManagementModule.class); + private final Class<? extends Provider<FibTableService>> fibTableServiceProvider; + + public FibManagementModule() { + this(FibTableServiceProvider.class); + } + + @VisibleForTesting + protected FibManagementModule(@Nonnull final Class<? extends Provider<FibTableService>> fibTableServiceProvider) { + this.fibTableServiceProvider = fibTableServiceProvider; + } + + @Override + protected void configure() { + LOG.info("Starting FibManagementModule initialization"); + // requests injection of properties + install(ConfigurationModule.create()); + bind(FibTableService.class).toProvider(fibTableServiceProvider).in(Singleton.class); + + LOG.debug("Injecting FibManagementModule reader factories"); + // creates reader factory binding + final Multibinder<ReaderFactory> readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + readerFactoryBinder.addBinding().to(FibManagementReaderFactory.class); + + LOG.debug("Injecting FibManagementModule writers factories"); + // create writer factory binding + final Multibinder<WriterFactory> writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + writerFactoryBinder.addBinding().to(FibManagementWriterFactory.class); + + LOG.info("FibManagementModule started successfully"); + } +} diff --git a/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/read/FibManagementReaderFactory.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/read/FibManagementReaderFactory.java new file mode 100644 index 000000000..d3adc91f7 --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/read/FibManagementReaderFactory.java @@ -0,0 +1,73 @@ +/* + * 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.fib.management.read; + +import com.google.inject.Inject; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.fib.management.FibManagementIIds; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +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 javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.FibTableManagementBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.vpp.fib.table.management.FibTablesBuilder; + +/** + * Factory producing readers for FIB management plugin's data. + */ +public final class FibManagementReaderFactory implements ReaderFactory, JvppReplyConsumer { + + @Inject + private FutureJVppCore vppApi; + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + final DumpCacheManager<IpFibDetailsReplyDump, Void> ipv4DumpManager = newIpv4RoutesDumpManager(vppApi); + final DumpCacheManager<Ip6FibDetailsReplyDump, Void> ipv6DumpManager = newIpv6RoutesDumpManager(vppApi); + + registry.addStructuralReader(FibManagementIIds.FIB_MNGMNT, FibTableManagementBuilder.class); + registry.addStructuralReader(FibManagementIIds.FM_FIB_TABLES, FibTablesBuilder.class); + registry.add(new GenericListReader<>(FibManagementIIds.FM_FTBLS_TABLE, + new FibTableCustomizer(ipv4DumpManager, ipv6DumpManager))); + } + + private DumpCacheManager<IpFibDetailsReplyDump, Void> newIpv4RoutesDumpManager( + @Nonnull final FutureJVppCore vppApi) { + return new DumpCacheManager.DumpCacheManagerBuilder<IpFibDetailsReplyDump, Void>() + .withExecutor( + (identifier, params) -> getReplyForRead(vppApi.ipFibDump(new IpFibDump()).toCompletableFuture(), + identifier)) + .acceptOnly(IpFibDetailsReplyDump.class) + .build(); + } + + private DumpCacheManager<Ip6FibDetailsReplyDump, Void> newIpv6RoutesDumpManager( + @Nonnull final FutureJVppCore vppApi) { + return new DumpCacheManager.DumpCacheManagerBuilder<Ip6FibDetailsReplyDump, Void>() + .withExecutor( + (identifier, params) -> getReplyForRead( + vppApi.ip6FibDump(new Ip6FibDump()).toCompletableFuture(), identifier)) + .acceptOnly(Ip6FibDetailsReplyDump.class) + .build(); + } +} diff --git a/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/read/FibTableCustomizer.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/read/FibTableCustomizer.java new file mode 100644 index 000000000..0151a1548 --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/read/FibTableCustomizer.java @@ -0,0 +1,119 @@ +/* + * 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.fib.management.read; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.vpp.jvpp.core.dto.Ip6FibDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.IpFibDetailsReplyDump; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.AddressFamilyIdentity; +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.FibTablesBuilder; +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.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +class FibTableCustomizer implements ListReaderCustomizer<Table, TableKey, TableBuilder>, ByteDataTranslator { + private final DumpCacheManager<IpFibDetailsReplyDump, Void> ipv4DumpManager; + private final DumpCacheManager<Ip6FibDetailsReplyDump, Void> ipv6DumpManager; + + FibTableCustomizer(final DumpCacheManager<IpFibDetailsReplyDump, Void> ipv4DumpManager, + final DumpCacheManager<Ip6FibDetailsReplyDump, Void> ipv6DumpManager) { + + this.ipv4DumpManager = ipv4DumpManager; + this.ipv6DumpManager = ipv6DumpManager; + } + + @Nonnull + @Override + public List<TableKey> getAllIds(@Nonnull final InstanceIdentifier<Table> instanceIdentifier, + @Nonnull final ReadContext readContext) throws ReadFailedException { + return Stream.concat(ipv4DumpManager.getDump(instanceIdentifier, readContext.getModificationCache()) + .or(new IpFibDetailsReplyDump()) + .ipFibDetails.stream() + .filter(ipFibDetails -> ipFibDetails.tableId >= 0) + .map(ipFibDetails -> new TableKey(Ipv4.class, new VniReference((long) ipFibDetails.tableId))) + .distinct(), + ipv6DumpManager.getDump(instanceIdentifier, readContext.getModificationCache()) + .or(new Ip6FibDetailsReplyDump()) + .ip6FibDetails.stream() + .filter(ip6FibDetails -> ip6FibDetails.tableId >= 0) + .map(ipFibDetails -> new TableKey(Ipv6.class, new VniReference((long) ipFibDetails.tableId)))) + .distinct() + .collect(Collectors.toList()); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<Table> list) { + ((FibTablesBuilder) builder).setTable(list); + } + + @Nonnull + @Override + public TableBuilder getBuilder(@Nonnull final InstanceIdentifier<Table> instanceIdentifier) { + return new TableBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Table> instanceIdentifier, + @Nonnull final TableBuilder builder, @Nonnull final ReadContext readContext) + throws ReadFailedException { + TableKey tableKey = instanceIdentifier.firstKeyOf(Table.class); + + if (tableKey.getAddressFamily().equals(Ipv4.class)) { + ipv4DumpManager.getDump(instanceIdentifier, readContext.getModificationCache()) + .or(new IpFibDetailsReplyDump()) + .ipFibDetails.stream() + .filter(ipFibDetails -> ipFibDetails.tableId == tableKey.getTableId().getValue().intValue()) + .findFirst().ifPresent( + ipFibDetails -> parseFibDetails(ipFibDetails.tableId, ipFibDetails.tableName, Ipv4.class, builder)); + + } else { + ipv6DumpManager.getDump(instanceIdentifier, readContext.getModificationCache()) + .or(new Ip6FibDetailsReplyDump()) + .ip6FibDetails.stream() + .filter(ipFibDetails -> ipFibDetails.tableId == tableKey.getTableId().getValue().intValue()) + .findFirst().ifPresent( + ipFibDetails -> parseFibDetails(ipFibDetails.tableId, ipFibDetails.tableName, Ipv6.class, builder)); + } + } + + private void parseFibDetails(final Integer tableId, final byte[] tableName, + final Class<? extends AddressFamilyIdentity> addressFamily, + final TableBuilder builder) { + builder.setAddressFamily(addressFamily) + .setTableId(new VniReference(Integer.toUnsignedLong(tableId))); + + if (tableName != null) { + // table name is optional + builder.setName(toString(tableName)); + } + } +} diff --git a/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/request/FibTableRequest.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/request/FibTableRequest.java new file mode 100644 index 000000000..6d6c69227 --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/request/FibTableRequest.java @@ -0,0 +1,102 @@ +/* + * 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.fib.management.request; + +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.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.IpTableAddDel; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.nio.charset.StandardCharsets; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class FibTableRequest implements AddressTranslator, JvppReplyConsumer { + + 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) { + this.api = api; + } + + public void checkValid() { + checkNotNull(getFibName(), "Fib table name not set"); + checkArgument(!getFibName().isEmpty(), "Fib table name must not be empty"); + } + + public void write(InstanceIdentifier<?> identifier) throws WriteFailedException { + sendRequest(identifier, ByteDataTranslator.BYTE_TRUE); + } + + public void delete(InstanceIdentifier<?> identifier) throws WriteFailedException { + sendRequest(identifier, ByteDataTranslator.BYTE_FALSE); + } + + private void sendRequest(final InstanceIdentifier<?> identifier, final byte isAdd) + throws WriteFailedException { + IpTableAddDel tableAddDel = new IpTableAddDel(); + tableAddDel.tableId = getFibTable(); + tableAddDel.isIpv6 = booleanToByte(isIpv6()); + tableAddDel.isAdd = isAdd; + if (getFibName() != null) { + // FIB table name is optional + tableAddDel.name = getFibName().getBytes(StandardCharsets.UTF_8); + } + getReplyForWrite(api.ipTableAddDel(tableAddDel).toCompletableFuture(), identifier); + } + + 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/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/services/FibTableService.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/services/FibTableService.java new file mode 100644 index 000000000..eef4df7fa --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/services/FibTableService.java @@ -0,0 +1,58 @@ +/* + * 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.fib.management.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 + */ + @Deprecated + 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/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/services/FibTableServiceImpl.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/services/FibTableServiceImpl.java new file mode 100644 index 000000000..01d264189 --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/services/FibTableServiceImpl.java @@ -0,0 +1,110 @@ +/* + * 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.fib.management.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.fib.management.FibManagementIIds; +import io.fd.hc2vpp.fib.management.request.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; + + public FibTableServiceImpl(@Nonnull FutureJVppCore futureJVppCore) { + super(futureJVppCore); + 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()); + 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(FibManagementIIds.FIB_MNGMNT, 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(FibManagementIIds.FIB_MNGMNT, cache, NO_PARAMS) + .toJavaUtil() + .map(ipFibDetailsReplyDump -> ipFibDetailsReplyDump.ipFibDetails) + .orElse(Collections.emptyList()) + .stream() + .map(ipFibDetails -> ipFibDetails.tableId); + } +} diff --git a/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/services/FibTableServiceProvider.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/services/FibTableServiceProvider.java new file mode 100644 index 000000000..d70f18e65 --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/services/FibTableServiceProvider.java @@ -0,0 +1,38 @@ +/* + * 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.fib.management.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); + } +} diff --git a/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/write/FibManagementWriterFactory.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/write/FibManagementWriterFactory.java new file mode 100644 index 000000000..781c6706b --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/write/FibManagementWriterFactory.java @@ -0,0 +1,39 @@ +/* + * 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.fib.management.write; + +import com.google.inject.Inject; +import io.fd.hc2vpp.fib.management.FibManagementIIds; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; + +/** + * Factory producing writers for FIB table management plugin's data. + */ +public final class FibManagementWriterFactory implements WriterFactory { + + @Inject + private FutureJVppCore vppApi; + + @Override + public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { + registry.add(new GenericListWriter<>(FibManagementIIds.FM_FTBLS_TABLE, new FibTableCustomizer(vppApi))); + } +} diff --git a/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/write/FibTableCustomizer.java b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/write/FibTableCustomizer.java new file mode 100644 index 000000000..74b8dc768 --- /dev/null +++ b/fib-management/fib-management-impl/src/main/java/io/fd/hc2vpp/fib/management/write/FibTableCustomizer.java @@ -0,0 +1,58 @@ +/* + * 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.fib.management.write; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.fib.management.request.FibTableRequest; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +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.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; + +class FibTableCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<Table, TableKey> { + FibTableCustomizer(@Nonnull final FutureJVppCore vppApi) { + super(vppApi); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Table> instanceIdentifier, + @Nonnull final Table table, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + bindFibTableRequest(table).write(instanceIdentifier); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Table> instanceIdentifier, + @Nonnull final Table table, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + bindFibTableRequest(table).delete(instanceIdentifier); + } + + private FibTableRequest bindFibTableRequest(final @Nonnull Table table) { + FibTableRequest fibTableRequest = new FibTableRequest(getFutureJVpp()); + fibTableRequest.setFibName(table.getName()); + fibTableRequest.setFibTable(table.getTableId().getValue().intValue()); + fibTableRequest.setIpv6(table.getAddressFamily().equals(Ipv6.class)); + return fibTableRequest; + } +} diff --git a/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/FibManagementModuleTest.java b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/FibManagementModuleTest.java new file mode 100644 index 000000000..f1f537114 --- /dev/null +++ b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/FibManagementModuleTest.java @@ -0,0 +1,99 @@ +/* + * 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.fib.management; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.Matchers.empty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import io.fd.hc2vpp.fib.management.read.FibManagementReaderFactory; +import io.fd.hc2vpp.fib.management.write.FibManagementWriterFactory; +import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; +import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.util.YangDAG; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.HashSet; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; + +public class FibManagementModuleTest { + + @Named("honeycomb-context") + @Bind + @Mock + private DataBroker honeycombContext; + + @Named("honeycomb-initializer") + @Bind + @Mock + private DataBroker honeycombInitializer; + + @Bind + @Mock + private FutureJVppCore futureJVppCore; + + @Inject + private Set<ReaderFactory> readerFactories = new HashSet<>(); + + @Inject + private Set<WriterFactory> writerFactories = new HashSet<>(); + + @Before + public void setUp() { + initMocks(this); + Guice.createInjector(new FibManagementModule(), BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testReaderFactories() { + assertThat(readerFactories, is(not(empty()))); + + // Test registration process (all dependencies present, topological order of readers does exist, etc.) + final CompositeReaderRegistryBuilder registryBuilder = new CompositeReaderRegistryBuilder(new YangDAG()); + readerFactories.forEach(factory -> factory.init(registryBuilder)); + assertNotNull(registryBuilder.build()); + assertEquals(1, readerFactories.size()); + assertTrue(readerFactories.iterator().next() instanceof FibManagementReaderFactory); + } + + @Test + public void testWriterFactories() { + assertThat(writerFactories, is(not(empty()))); + + // Test registration process (all dependencies present, topological order of writers does exist, etc.) + final FlatWriterRegistryBuilder registryBuilder = new FlatWriterRegistryBuilder(new YangDAG()); + writerFactories.forEach(factory -> factory.init(registryBuilder)); + assertNotNull(registryBuilder.build()); + assertEquals(1, writerFactories.size()); + assertTrue(writerFactories.iterator().next() instanceof FibManagementWriterFactory); + } +} diff --git a/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/helpers/SchemaContextTestHelper.java b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/helpers/SchemaContextTestHelper.java new file mode 100644 index 000000000..1341e7e86 --- /dev/null +++ b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/helpers/SchemaContextTestHelper.java @@ -0,0 +1,31 @@ +/* + * 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.fib.management.helpers; + +import com.google.common.collect.ImmutableSet; +import io.fd.honeycomb.test.tools.annotations.InjectablesProcessor; +import io.fd.honeycomb.test.tools.annotations.SchemaContextProvider; +import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.$YangModuleInfoImpl; + +public interface SchemaContextTestHelper extends InjectablesProcessor { + + @SchemaContextProvider + default ModuleInfoBackedContext getSchemaContext() { + return provideSchemaContextFor(ImmutableSet.of($YangModuleInfoImpl.getInstance())); + } +} diff --git a/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/read/FibTableCustomizerTest.java b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/read/FibTableCustomizerTest.java new file mode 100644 index 000000000..6b2d8c4d7 --- /dev/null +++ b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/read/FibTableCustomizerTest.java @@ -0,0 +1,172 @@ +/* + * 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.fib.management.read; + +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.fib.management.FibManagementIIds; +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.vpp.jvpp.core.dto.Ip6FibDetails; +import io.fd.vpp.jvpp.core.dto.Ip6FibDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.IpFibDetails; +import io.fd.vpp.jvpp.core.dto.IpFibDetailsReplyDump; +import io.fd.vpp.jvpp.core.types.FibPath; +import java.util.Collections; +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +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.FibTablesBuilder; +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; + +public class FibTableCustomizerTest extends ListReaderCustomizerTest<Table, TableKey, TableBuilder> implements + AddressTranslator { + + private static final String IPV4_VRF_1 = "IPV4_VRF_1"; + private static final IpAddress NEXT_HOP_1 = new IpAddress(new Ipv6Address("a::1")); + private static final IpAddress NEXT_HOP_2 = new IpAddress(new Ipv4Address("10.0.0.254")); + private static final InstanceIdentifier<Table> TABLE_V4_ID = + FibManagementIIds.FM_FIB_TABLES.child(Table.class, new TableKey(Ipv4.class, new VniReference(1L))); + private static final InstanceIdentifier<Table> TABLE_V6_ID = + FibManagementIIds.FM_FIB_TABLES.child(Table.class, new TableKey(Ipv6.class, new VniReference(1L))); + private static final IpAddress IP_ADDR_1 = new IpAddress(new Ipv6Address("a::")); + private static final IpAddress IP_ADDR_2 = new IpAddress(new Ipv4Address("10.0.0.1")); + private DumpCacheManager<Ip6FibDetailsReplyDump, Void> manager_v6; + private DumpCacheManager<IpFibDetailsReplyDump, Void> manager_v4; + + @Mock + private EntityDumpExecutor<Ip6FibDetailsReplyDump, Void> executor_v6; + + @Mock + private EntityDumpExecutor<IpFibDetailsReplyDump, Void> executor_v4; + + @Mock + private ModificationCache cache; + + public FibTableCustomizerTest() { + super(Table.class, FibTablesBuilder.class); + } + + @Override + public void setUp() throws ReadFailedException { + manager_v6 = new DumpCacheManager.DumpCacheManagerBuilder<Ip6FibDetailsReplyDump, Void>() + .withExecutor(executor_v6) + .acceptOnly(Ip6FibDetailsReplyDump.class) + .build(); + manager_v4 = new DumpCacheManager.DumpCacheManagerBuilder<IpFibDetailsReplyDump, Void>() + .withExecutor(executor_v4) + .acceptOnly(IpFibDetailsReplyDump.class) + .build(); + + when(executor_v6.executeDump(any(), any())).thenReturn(replyDumpV6()); + when(executor_v4.executeDump(any(), any())).thenReturn(replyDumpV4()); + when(ctx.getModificationCache()).thenReturn(cache); + } + + private Ip6FibDetailsReplyDump replyDumpV6() { + Ip6FibDetailsReplyDump replyDump = new Ip6FibDetailsReplyDump(); + + //simple + Ip6FibDetails ip6FibDetails = new Ip6FibDetails(); + ip6FibDetails.tableId = 1; + ip6FibDetails.address = ipAddressToArray(IP_ADDR_1); + ip6FibDetails.addressLength = 22; + ip6FibDetails.path = new FibPath[]{}; + + FibPath path = new FibPath(); + path.weight = 3; + path.nextHop = ipAddressToArray(NEXT_HOP_1); + path.afi = 0; + path.swIfIndex = 1; + ip6FibDetails.path = new FibPath[]{path}; + + replyDump.ip6FibDetails = Collections.singletonList(ip6FibDetails); + return replyDump; + } + + private IpFibDetailsReplyDump replyDumpV4() { + IpFibDetailsReplyDump replyDump = new IpFibDetailsReplyDump(); + + //simple + IpFibDetails detail = new IpFibDetails(); + detail.tableId = 1; + detail.address = ipAddressToArray(IP_ADDR_2); + detail.addressLength = 24; + detail.tableName = IPV4_VRF_1.getBytes(); + detail.path = new FibPath[]{}; + + FibPath path = new FibPath(); + path.weight = 3; + path.nextHop = ipAddressToArray(NEXT_HOP_2); + path.afi = 0; + path.swIfIndex = 1; + detail.path = new FibPath[]{path}; + + replyDump.ipFibDetails = Collections.singletonList(detail); + return replyDump; + } + + @Test + public void getAllIds() throws Exception { + final List<TableKey> keys = getCustomizer().getAllIds(TABLE_V6_ID, ctx); + + assertThat(keys, hasSize(2)); + assertThat(keys, hasItems(new TableKey(Ipv6.class, new VniReference(1L)), + new TableKey(Ipv4.class, new VniReference(1L)))); + } + + @Test + public void readCurrentAttributesSimpleHop() throws Exception { + TableBuilder builder = new TableBuilder(); + getCustomizer().readCurrentAttributes(TABLE_V6_ID, builder, ctx); + + Assert.assertEquals(Ipv6.class, builder.getAddressFamily()); + Assert.assertEquals(1L, builder.getTableId().getValue().longValue()); + Assert.assertNull(builder.getName()); + + builder = new TableBuilder(); + getCustomizer().readCurrentAttributes(TABLE_V4_ID, builder, ctx); + + Assert.assertEquals(Ipv4.class, builder.getAddressFamily()); + Assert.assertEquals(1L, builder.getTableId().getValue().longValue()); + Assert.assertEquals(IPV4_VRF_1, builder.getName()); + } + + @Override + protected ReaderCustomizer<Table, TableBuilder> initCustomizer() { + return new FibTableCustomizer(manager_v4, manager_v6); + } +} diff --git a/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/services/FibTableServiceImplTest.java b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/services/FibTableServiceImplTest.java new file mode 100644 index 000000000..2351ead2c --- /dev/null +++ b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/services/FibTableServiceImplTest.java @@ -0,0 +1,103 @@ +/* + * 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.fib.management.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.test.util.FutureProducer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.fib.management.FibManagementIIds; +import io.fd.hc2vpp.fib.management.helpers.SchemaContextTestHelper; +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.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 SchemaContextTestHelper, ByteDataTranslator, FutureProducer { + + private static final int FIB_TABLE_ID = 123456; + private static final String FIB_TABLE_NAME = "VRF123456"; + + @Inject + @Mock + private static FutureJVppCore api; + + @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); + fibService.checkTableExist(FIB_TABLE_ID, modificationCache); + } + + @Test + public void writeIpv4Test() throws WriteFailedException { + FibTableServiceImpl fibTableService = new FibTableServiceImpl(api); + fibTableService.write(FibManagementIIds.FIB_MNGMNT, FIB_TABLE_ID, FIB_TABLE_NAME, false); + + verify(api, times(1)).ipTableAddDel(argumentCaptor.capture()); + + assertTableAddDelRequest(argumentCaptor.getValue(), false); + } + + @Test + public void writeIpv6Test() throws WriteFailedException { + FibTableServiceImpl fibTableService = new FibTableServiceImpl(api); + fibTableService.write(FibManagementIIds.FIB_MNGMNT, FIB_TABLE_ID, FIB_TABLE_NAME, true); + + verify(api, times(1)).ipTableAddDel(argumentCaptor.capture()); + + assertTableAddDelRequest(argumentCaptor.getValue(), true); + } + + private void assertTableAddDelRequest(IpTableAddDel jvppRequest, boolean isIpv6) { + assertEquals(ByteDataTranslator.BYTE_TRUE, 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/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/write/FibTableCustomizerTest.java b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/write/FibTableCustomizerTest.java new file mode 100644 index 000000000..c9d05dc45 --- /dev/null +++ b/fib-management/fib-management-impl/src/test/java/io/fd/hc2vpp/fib/management/write/FibTableCustomizerTest.java @@ -0,0 +1,89 @@ +/* + * 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.fib.management.write; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.fib.management.FibManagementIIds; +import io.fd.hc2vpp.fib.management.helpers.SchemaContextTestHelper; +import io.fd.honeycomb.test.tools.HoneycombTestRunner; +import io.fd.honeycomb.test.tools.annotations.InjectTestData; +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.IpTableAddDel; +import io.fd.vpp.jvpp.core.dto.IpTableAddDelReply; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +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.FibTables; +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; + +@RunWith(HoneycombTestRunner.class) +public class FibTableCustomizerTest extends WriterCustomizerTest implements SchemaContextTestHelper, + ByteDataTranslator { + private static final String FIB_PATH = + "/vpp-fib-table-management:fib-table-management/vpp-fib-table-management:fib-tables"; + private static final String IPV4_VRF_0 = "ipv4-VRF:0"; + private static final String IPV6_VRF_0 = "ipv6-VRF:0"; + @Mock + private ModificationCache modificationCache; + private FibTableCustomizer customizer; + + @Override + protected void setUpTest() { + customizer = new FibTableCustomizer(api); + when(writeContext.getModificationCache()).thenReturn(modificationCache); + when(api.ipTableAddDel(any())).thenReturn(future(new IpTableAddDelReply())); + } + + @Test + public void testWriteSimple(@InjectTestData(resourcePath = "/fib.json", id = FIB_PATH) FibTables tables) + throws WriteFailedException { + final Table data = tables.getTable().get(0); + customizer.writeCurrentAttributes(FibManagementIIds.FM_FIB_TABLES + .child(Table.class, new TableKey(Ipv6.class, new VniReference(0L))), data, writeContext); + final IpTableAddDel request = new IpTableAddDel(); + request.isAdd = 1; + request.isIpv6 = 0; + request.tableId = 0; + request.name = IPV4_VRF_0.getBytes(); + + verify(api).ipTableAddDel(request); + } + + @Test + public void testDelete(@InjectTestData(resourcePath = "/fib.json", id = FIB_PATH) FibTables tables) + throws WriteFailedException { + final Table data = tables.getTable().get(3); + customizer.deleteCurrentAttributes(FibManagementIIds.FM_FIB_TABLES + .child(Table.class, new TableKey(Ipv6.class, new VniReference(0L))), data, writeContext); + final IpTableAddDel request = new IpTableAddDel(); + request.isAdd = 0; + request.isIpv6 = 1; + request.tableId = 0; + request.name = IPV6_VRF_0.getBytes(); + + verify(api).ipTableAddDel(request); + } +} diff --git a/fib-management/fib-management-impl/src/test/resources/fib.json b/fib-management/fib-management-impl/src/test/resources/fib.json new file mode 100644 index 000000000..a96ca2866 --- /dev/null +++ b/fib-management/fib-management-impl/src/test/resources/fib.json @@ -0,0 +1,26 @@ +{ + "fib-tables": { + "vpp-fib-table-management:table": [ + { + "table-id": 0, + "address-family": "vpp-fib-table-management:ipv4", + "name": "ipv4-VRF:0" + }, + { + "table-id": 12, + "address-family": "vpp-fib-table-management:ipv4", + "name": "ipv4-VRF:12" + }, + { + "table-id": 0, + "address-family": "vpp-fib-table-management:ipv6", + "name": "ipv6-VRF:0" + }, + { + "table-id": 25, + "address-family": "vpp-fib-table-management:ipv6", + "name": "ipv6-VRF:25" + } + ] + } +} |