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/main | |
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/main')
10 files changed, 697 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; + } +} |