diff options
author | Jan Srnicek <jsrnicek@cisco.com> | 2016-12-01 18:15:52 +0100 |
---|---|---|
committer | Jan Srnicek <jsrnicek@cisco.com> | 2016-12-01 18:16:47 +0100 |
commit | 32aa07e5517fba7f78ae79d2ba83b56f72a53293 (patch) | |
tree | 26256f30f2dc5c3521403ef3fcd2e038b2f9bca6 /routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read | |
parent | 9c9935c83ce9869ca36cbde7865423ef02f19db8 (diff) |
HONEYCOMB-58 - Routing Plugin Structure
Read/Write support for ipv4/6 static routes.
Restriction due to vpp implementation described
in readme.
Change-Id: I328f406a9b7cb8781f8becf98eca293cebe66859
Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
Diffstat (limited to 'routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read')
8 files changed, 1004 insertions, 0 deletions
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv4ReadRoutingNodes.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv4ReadRoutingNodes.java new file mode 100644 index 000000000..dde2f9c46 --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv4ReadRoutingNodes.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016 Cisco 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.read; + + +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.MultiNamingContext; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.routing.RoutingConfiguration; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +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.Set; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.StaticRoutes2; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.StaticRoutes2Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.Route; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.VppIpv4RouteState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.next.hop.options.next.hop.list.NextHopList; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.next.hop.options.next.hop.list.next.hop.list.NextHop; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol.StaticRoutes; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +interface Ipv4ReadRoutingNodes extends JvppReplyConsumer { + + static InstanceIdentifier<StaticRoutes2> staticRoutesInstanceIdentifier( + final InstanceIdentifier<StaticRoutes> staticRoutesInstanceIdentifier) { + return staticRoutesInstanceIdentifier.augmentation(StaticRoutes2.class); + } + + static InstanceIdentifier<Ipv4> ipv4Identifier( + final InstanceIdentifier<StaticRoutes2> staticRoutes2InstanceIdentifier) { + return staticRoutes2InstanceIdentifier.child(Ipv4.class); + } + + default 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(); + } + + default void registerIpv4Routes(@Nonnull final InstanceIdentifier<StaticRoutes> subTreeId, + @Nonnull final ModifiableReaderRegistryBuilder registry, + @Nonnull final DumpCacheManager<IpFibDetailsReplyDump, Void> ipv4DumpManager, + @Nonnull final RoutingConfiguration configuration, + @Nonnull final MultiNamingContext routeHopContext, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext routeContext, + @Nonnull final NamingContext routingProtocolContext) { + + final InstanceIdentifier<StaticRoutes2> staticRoutes2InstanceIdentifier = + staticRoutesInstanceIdentifier(subTreeId); + final InstanceIdentifier<Ipv4> ipv4InstanceIdentifier = ipv4Identifier(staticRoutes2InstanceIdentifier); + + registry.addStructuralReader(staticRoutes2InstanceIdentifier, StaticRoutes2Builder.class); + + registry.addStructuralReader(ipv4InstanceIdentifier, Ipv4Builder.class); + registry.subtreeAdd(ipv4RoutingHandledChildren(InstanceIdentifier.create(Route.class)), + new GenericListReader<>(ipv4InstanceIdentifier.child(Route.class), + new Ipv4RouteCustomizer(ipv4DumpManager, configuration, routeHopContext, interfaceContext, + routeContext, routingProtocolContext))); + } + + default Set<InstanceIdentifier<?>> ipv4RoutingHandledChildren( + final InstanceIdentifier<Route> parent) { + return ImmutableSet.of(parent.child(NextHopList.class), + parent.child(NextHopList.class).child(NextHop.class), + parent.child(VppIpv4RouteState.class)); + } + +} diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv4RouteCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv4RouteCustomizer.java new file mode 100644 index 000000000..71758b4fe --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv4RouteCustomizer.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016 Cisco 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.read; + +import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.translate.util.MultiNamingContext; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.routing.RoutingConfiguration; +import io.fd.hc2vpp.routing.naming.Ipv4RouteNamesFactory; +import io.fd.hc2vpp.routing.trait.Ipv4RoutePathParser; +import io.fd.hc2vpp.routing.trait.RouteMapper; +import io.fd.honeycomb.translate.MappingContext; +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.IpFibDetails; +import io.fd.vpp.jvpp.core.dto.IpFibDetailsReplyDump; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.Route; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.RouteBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.RouteKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.VppIpv4RouteStateBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.RoutingProtocol; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class Ipv4RouteCustomizer + implements ListReaderCustomizer<Route, RouteKey, RouteBuilder>, RouteMapper, Ipv4RoutePathParser { + + + private final DumpCacheManager<IpFibDetailsReplyDump, Void> ipv4RoutesDumpManager; + private final RoutingConfiguration configuration; + private final MultiNamingContext routeHopContext; + private final NamingContext interfaceContext; + private final NamingContext routesContext; + private final NamingContext routingProtocolContext; + + private final Ipv4RouteNamesFactory namesFactory; + + public Ipv4RouteCustomizer(@Nonnull final DumpCacheManager<IpFibDetailsReplyDump, Void> ipv4RoutesDumpManager, + @Nonnull final RoutingConfiguration configuration, + @Nonnull final MultiNamingContext routeHopContext, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext routesContext, + @Nonnull final NamingContext routingProtocolContext) { + this.ipv4RoutesDumpManager = ipv4RoutesDumpManager; + this.configuration = configuration; + this.interfaceContext = interfaceContext; + this.routeHopContext = routeHopContext; + this.routesContext = routesContext; + this.routingProtocolContext = routingProtocolContext; + this.namesFactory = new Ipv4RouteNamesFactory(interfaceContext, routingProtocolContext); + } + + @Nonnull + @Override + public List<RouteKey> getAllIds(@Nonnull final InstanceIdentifier<Route> instanceIdentifier, + @Nonnull final ReadContext readContext) throws ReadFailedException { + + final Optional<IpFibDetailsReplyDump> ipv4RoutesDump = + ipv4RoutesDumpManager.getDump(instanceIdentifier, readContext.getModificationCache(), NO_PARAMS); + + final String protocolName = instanceIdentifier.firstKeyOf(RoutingProtocol.class).getName(); + final int protocolTableId = routingProtocolContext.getIndex(protocolName, readContext.getMappingContext()); + + return ipv4RoutesDump.isPresent() + ? ipv4RoutesDump.get().ipFibDetails.stream() + .filter(details -> protocolTableId == details.tableId) + .map(ipFibDetails -> toKey(ipFibDetails, readContext.getMappingContext())) + .collect(Collectors.toList()) + : Collections.emptyList(); + } + + /** + * route id is represented as number, but there's no index in dumped data, + * so index is assigned to name formatted as tableId_address_addressLength(should be unique combination) + */ + private RouteKey toKey(final IpFibDetails details, final MappingContext mappingContext) { + String routeName = namesFactory.uniqueRouteName(details, mappingContext); + // first condition excludes data written manually, second one data that has been already learned + if (!routesContext.containsIndex(routeName, mappingContext)) { + String learnedRouteName = nameWithPrefix(configuration.getLearnedRouteNamePrefix(), routeName); + if (!routesContext.containsIndex(learnedRouteName, mappingContext)) { + routesContext.addName(learnedRouteName, mappingContext); + } + return keyForName(mappingContext, learnedRouteName); + } + return keyForName(mappingContext, routeName); + } + + private RouteKey keyForName(final MappingContext mappingContext, final String name) { + return new RouteKey( + Long.valueOf(routesContext.getIndex(name, mappingContext))); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<Route> list) { + Ipv4Builder.class.cast(builder).setRoute(list); + } + + @Nonnull + @Override + public RouteBuilder getBuilder(@Nonnull final InstanceIdentifier<Route> instanceIdentifier) { + return new RouteBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Route> instanceIdentifier, + @Nonnull final RouteBuilder routeBuilder, @Nonnull final ReadContext readContext) + throws ReadFailedException { + final RouteKey key = instanceIdentifier.firstKeyOf(Route.class); + final String mappedName = routesContext.getName(key.getId().intValue(), readContext.getMappingContext()); + final String protocolName = instanceIdentifier.firstKeyOf(RoutingProtocol.class).getName(); + final int protocolTableId = routingProtocolContext.getIndex(protocolName, readContext.getMappingContext()); + final Optional<IpFibDetailsReplyDump> ipv4RoutesDump = + ipv4RoutesDumpManager.getDump(instanceIdentifier, readContext.getModificationCache(), NO_PARAMS); + + if (ipv4RoutesDump.isPresent() && !ipv4RoutesDump.get().ipFibDetails.isEmpty()) { + + final java.util.Optional<IpFibDetails> opDetail = ipv4RoutesDump.get().ipFibDetails.stream() + .filter(details -> protocolTableId == details.tableId) + .filter(details -> equalsWithConfigOrLearned(configuration.getLearnedRouteNamePrefix(), mappedName, + namesFactory.uniqueRouteName(details, readContext.getMappingContext()))) + .findAny(); + + if (opDetail.isPresent()) { + final IpFibDetails detail = opDetail.get(); + + routeBuilder.setNextHopOptions( + resolveHopType(mappedName, Arrays.asList(detail.path), interfaceContext, routeHopContext, + readContext.getMappingContext(), namesFactory)) + .setKey(key) + .setId(key.getId()) + .setDestinationPrefix(toIpv4Prefix(detail.address, toJavaByte(detail.addressLength))) + .setVppIpv4RouteState(new VppIpv4RouteStateBuilder().build()); + } + } + } +} diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv6ReadRoutingNodes.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv6ReadRoutingNodes.java new file mode 100644 index 000000000..06eaaf913 --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv6ReadRoutingNodes.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016 Cisco 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.read; + +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.MultiNamingContext; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.routing.RoutingConfiguration; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +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.future.FutureJVppCore; +import java.util.Set; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.StaticRoutes2; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.StaticRoutes2Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv6; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv6.Route; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv6.route.VppIpv6RouteState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv6.route.next.hop.options.next.hop.list.NextHopList; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv6.route.next.hop.options.next.hop.list.next.hop.list.NextHop; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol.StaticRoutes; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +interface Ipv6ReadRoutingNodes extends JvppReplyConsumer { + + static InstanceIdentifier<StaticRoutes2> staticRoutesInstanceIdentifier( + final InstanceIdentifier<StaticRoutes> staticRoutesInstanceIdentifier) { + return staticRoutesInstanceIdentifier.augmentation(StaticRoutes2.class); + } + + static InstanceIdentifier<Ipv6> ipv6Identifier( + final InstanceIdentifier<StaticRoutes2> staticRoutes2InstanceIdentifier) { + return staticRoutes2InstanceIdentifier.child(Ipv6.class); + } + + default 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(); + } + + default void registerIpv6Routes(@Nonnull final InstanceIdentifier<StaticRoutes> subTreeId, + @Nonnull final ModifiableReaderRegistryBuilder registry, + @Nonnull final DumpCacheManager<Ip6FibDetailsReplyDump, Void> ipv6DumpManager, + @Nonnull final RoutingConfiguration configuration, + @Nonnull final MultiNamingContext routeHopContext, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext routeContext, + @Nonnull final NamingContext routingProtocolContext) { + + final InstanceIdentifier<StaticRoutes2> staticRoutes2InstanceIdentifier = + staticRoutesInstanceIdentifier(subTreeId); + final InstanceIdentifier<Ipv6> ipv6InstanceIdentifier = ipv6Identifier(staticRoutes2InstanceIdentifier); + + registry.addStructuralReader(staticRoutes2InstanceIdentifier, StaticRoutes2Builder.class); + + registry.addStructuralReader(ipv6InstanceIdentifier, Ipv6Builder.class); + registry.subtreeAdd(ipv6RoutingHandledChildren(InstanceIdentifier.create(Route.class)), + new GenericListReader<>(ipv6InstanceIdentifier.child(Route.class), + new Ipv6RouteCustomizer(ipv6DumpManager, configuration, routeHopContext, interfaceContext, + routeContext, routingProtocolContext))); + } + + default Set<InstanceIdentifier<?>> ipv6RoutingHandledChildren( + final InstanceIdentifier<Route> parent) { + return ImmutableSet.of(parent.child(NextHopList.class), + parent.child(NextHopList.class).child(NextHop.class), + parent.child(VppIpv6RouteState.class)); + } + +} diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv6RouteCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv6RouteCustomizer.java new file mode 100644 index 000000000..c83891d85 --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/Ipv6RouteCustomizer.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016 Cisco 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.read; + +import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.translate.util.MultiNamingContext; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.routing.RoutingConfiguration; +import io.fd.hc2vpp.routing.naming.Ipv6RouteNamesFactory; +import io.fd.hc2vpp.routing.trait.Ipv6RoutePathParser; +import io.fd.hc2vpp.routing.trait.RouteMapper; +import io.fd.honeycomb.translate.MappingContext; +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.Ip6FibDetails; +import io.fd.vpp.jvpp.core.dto.Ip6FibDetailsReplyDump; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv6.Route; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv6.RouteBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv6.RouteKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.state.routing.instance.routing.protocols.routing.protocol._static.routes.ipv6.route.VppIpv6RouteStateBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.RoutingProtocol; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class Ipv6RouteCustomizer + implements ListReaderCustomizer<Route, RouteKey, RouteBuilder>, RouteMapper, Ipv6RoutePathParser { + + private final DumpCacheManager<Ip6FibDetailsReplyDump, Void> ipv6RoutesDumpManager; + private final RoutingConfiguration configuration; + private final MultiNamingContext routeHopContext; + private final NamingContext interfaceContext; + private final NamingContext routesContext; + private final NamingContext routingProtocolContext; + private final Ipv6RouteNamesFactory namesFactory; + + public Ipv6RouteCustomizer(@Nonnull final DumpCacheManager<Ip6FibDetailsReplyDump, Void> ipv6RoutesDumpManager, + @Nonnull final RoutingConfiguration configuration, + @Nonnull final MultiNamingContext routeHopContext, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext routesContext, + @Nonnull final NamingContext routingProtocolContext) { + this.ipv6RoutesDumpManager = ipv6RoutesDumpManager; + this.configuration = configuration; + this.interfaceContext = interfaceContext; + this.routeHopContext = routeHopContext; + this.routesContext = routesContext; + this.routingProtocolContext = routingProtocolContext; + this.namesFactory = new Ipv6RouteNamesFactory(interfaceContext, routingProtocolContext); + } + + @Nonnull + @Override + public List<RouteKey> getAllIds(@Nonnull final InstanceIdentifier<Route> instanceIdentifier, + @Nonnull final ReadContext readContext) throws ReadFailedException { + + final Optional<Ip6FibDetailsReplyDump> ipv6RoutesDump = + ipv6RoutesDumpManager.getDump(instanceIdentifier, readContext.getModificationCache(), NO_PARAMS); + + final String protocolName = instanceIdentifier.firstKeyOf(RoutingProtocol.class).getName(); + final int protocolTableId = routingProtocolContext.getIndex(protocolName, readContext.getMappingContext()); + + return ipv6RoutesDump.isPresent() + ? ipv6RoutesDump.get().ip6FibDetails.stream() + .filter(details -> protocolTableId == details.tableId) + .map(ip6FibDetails -> toKey(ip6FibDetails, readContext.getMappingContext())) + .collect(Collectors.toList()) + : Collections.emptyList(); + } + + /** + * route id is represented as number, but there's no index in dumped data, + * so index is assigned to name formatted as tableId_address_addressLength(should be unique combination) + */ + private RouteKey toKey(final Ip6FibDetails details, final MappingContext mappingContext) { + String routeName = namesFactory.uniqueRouteName(details, mappingContext); + // first condition excludes data written manually, second one data that has been already learned + if (!routesContext.containsIndex(routeName, mappingContext)) { + String learnedRouteName = nameWithPrefix(configuration.getLearnedRouteNamePrefix(), routeName); + if (!routesContext.containsIndex(learnedRouteName, mappingContext)) { + routesContext.addName(learnedRouteName, mappingContext); + } + return keyForName(mappingContext, learnedRouteName); + } + return keyForName(mappingContext, routeName); + } + + private RouteKey keyForName(final MappingContext mappingContext, final String name) { + return new RouteKey(Long.valueOf(routesContext.getIndex(name, mappingContext))); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<Route> list) { + Ipv6Builder.class.cast(builder).setRoute(list); + } + + @Nonnull + @Override + public RouteBuilder getBuilder(@Nonnull final InstanceIdentifier<Route> instanceIdentifier) { + return new RouteBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Route> instanceIdentifier, + @Nonnull final RouteBuilder routeBuilder, @Nonnull final ReadContext readContext) + throws ReadFailedException { + final RouteKey key = instanceIdentifier.firstKeyOf(Route.class); + final String mappedName = routesContext.getName(key.getId().intValue(), readContext.getMappingContext()); + final String protocolName = instanceIdentifier.firstKeyOf(RoutingProtocol.class).getName(); + final int protocolTableId = routingProtocolContext.getIndex(protocolName, readContext.getMappingContext()); + final Optional<Ip6FibDetailsReplyDump> ipv6RoutesDump = + ipv6RoutesDumpManager.getDump(instanceIdentifier, readContext.getModificationCache(), NO_PARAMS); + + if (ipv6RoutesDump.isPresent() && !ipv6RoutesDump.get().ip6FibDetails.isEmpty()) { + + final java.util.Optional<Ip6FibDetails> opDetail = ipv6RoutesDump.get().ip6FibDetails.stream() + .filter(details -> protocolTableId == details.tableId) + .filter(details -> equalsWithConfigOrLearned(configuration.getLearnedRouteNamePrefix(), mappedName, + namesFactory.uniqueRouteName(details, readContext.getMappingContext()))) + .findAny(); + + if (opDetail.isPresent()) { + final Ip6FibDetails detail = opDetail.get(); + + routeBuilder.setNextHopOptions( + resolveHopType(mappedName, Arrays.asList(detail.path), interfaceContext, routeHopContext, + readContext.getMappingContext(), namesFactory)) + .setKey(key) + .setId(key.getId()) + .setDestinationPrefix(toIpv6Prefix(detail.address, toJavaByte(detail.addressLength))) + .setVppIpv6RouteState(new VppIpv6RouteStateBuilder().build()); + } + } + } +} diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingInstanceCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingInstanceCustomizer.java new file mode 100644 index 000000000..78e869f9a --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingInstanceCustomizer.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016 Cisco 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.read; + +import com.google.common.collect.ImmutableList; +import io.fd.hc2vpp.routing.RoutingConfiguration; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.RoutingStateBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.StandardRoutingInstance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.RoutingInstance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.RoutingInstanceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.RoutingInstanceKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Returns default instance of routing instance + */ +public class RoutingInstanceCustomizer + implements ListReaderCustomizer<RoutingInstance, RoutingInstanceKey, RoutingInstanceBuilder> { + + private RoutingInstanceKey defaultKey; + + public RoutingInstanceCustomizer(@Nonnull final RoutingConfiguration configuration) { + defaultKey = new RoutingInstanceKey(configuration.getDefaultRoutingInstanceName()); + } + + @Nonnull + @Override + public List<RoutingInstanceKey> getAllIds(@Nonnull final InstanceIdentifier<RoutingInstance> instanceIdentifier, + @Nonnull final ReadContext readContext) throws ReadFailedException { + return ImmutableList.of(defaultKey); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<RoutingInstance> list) { + RoutingStateBuilder.class.cast(builder).setRoutingInstance(list); + } + + @Nonnull + @Override + public RoutingInstanceBuilder getBuilder(@Nonnull final InstanceIdentifier<RoutingInstance> instanceIdentifier) { + return new RoutingInstanceBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<RoutingInstance> instanceIdentifier, + @Nonnull final RoutingInstanceBuilder routingInstanceBuilder, + @Nonnull final ReadContext readContext) throws ReadFailedException { + routingInstanceBuilder.setType(StandardRoutingInstance.class) + .setKey(defaultKey) + .setName(defaultKey.getName()); + } +} diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingProtocolCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingProtocolCustomizer.java new file mode 100644 index 000000000..c8a379b83 --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingProtocolCustomizer.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016 Cisco 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.read; + +import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.routing.trait.RouteMapper; +import io.fd.honeycomb.translate.ModificationCache; +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.Collection; +import java.util.Collections; +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.ietf.params.xml.ns.yang.ietf.routing.rev140524.Static; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.RoutingProtocolsBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.RoutingProtocol; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.RoutingProtocolBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.RoutingProtocolKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.RoutingProtocolStateVppAttr; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.RoutingProtocolStateVppAttrBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.VniReference; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.routing.state.routing.instance.routing.protocols.routing.protocol.VppProtocolStateAttributesBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + + +public class RoutingProtocolCustomizer + implements ListReaderCustomizer<RoutingProtocol, RoutingProtocolKey, RoutingProtocolBuilder>, RouteMapper { + + private final NamingContext routingProtocolContext; + private final DumpCacheManager<IpFibDetailsReplyDump, Void> ipv4RoutesDumpManager; + private final DumpCacheManager<Ip6FibDetailsReplyDump, Void> ipv6RoutesDumpManager; + + + public RoutingProtocolCustomizer(@Nonnull final NamingContext routingProtocolContext, + @Nonnull final DumpCacheManager<IpFibDetailsReplyDump, Void> ipv4RoutesDumpManager, + @Nonnull final DumpCacheManager<Ip6FibDetailsReplyDump, Void> ipv6RoutesDumpManager) { + this.routingProtocolContext = routingProtocolContext; + this.ipv4RoutesDumpManager = ipv4RoutesDumpManager; + this.ipv6RoutesDumpManager = ipv6RoutesDumpManager; + } + + @Nonnull + @Override + public List<RoutingProtocolKey> getAllIds(@Nonnull final InstanceIdentifier<RoutingProtocol> instanceIdentifier, + @Nonnull final ReadContext readContext) throws ReadFailedException { + + final ModificationCache modificationCache = readContext.getModificationCache(); + + // builds keys from routing protocol prefix and unique set of table ids + return Stream.of( + ipv4TableIds(instanceIdentifier, modificationCache), + ipv6TableIds(instanceIdentifier, modificationCache)) + .flatMap(Collection::stream) + .map(tableId -> routingProtocolContext.getName(tableId, readContext.getMappingContext())) + .distinct() + .map(RoutingProtocolKey::new) + .collect(Collectors.toList()); + } + + private List<Integer> ipv4TableIds(final InstanceIdentifier<RoutingProtocol> instanceIdentifier, + final ModificationCache modificationCache) throws ReadFailedException { + final Optional<IpFibDetailsReplyDump> + ipv4Routes = ipv4RoutesDumpManager.getDump(instanceIdentifier, modificationCache, NO_PARAMS); + + if (ipv4Routes.isPresent()) { + return ipv4Routes.get().ipFibDetails.stream() + .map(ipFibDetails -> ipFibDetails.tableId) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } + + private List<Integer> ipv6TableIds(final InstanceIdentifier<RoutingProtocol> instanceIdentifier, + final ModificationCache modificationCache) throws ReadFailedException { + final Optional<Ip6FibDetailsReplyDump> + ipv6Routes = ipv6RoutesDumpManager.getDump(instanceIdentifier, modificationCache, NO_PARAMS); + + if (ipv6Routes.isPresent()) { + return ipv6Routes.get().ip6FibDetails.stream() + .map(ipFibDetails -> ipFibDetails.tableId) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<RoutingProtocol> list) { + RoutingProtocolsBuilder.class.cast(builder).setRoutingProtocol(list); + } + + @Nonnull + @Override + public RoutingProtocolBuilder getBuilder(@Nonnull final InstanceIdentifier<RoutingProtocol> instanceIdentifier) { + return new RoutingProtocolBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<RoutingProtocol> instanceIdentifier, + @Nonnull final RoutingProtocolBuilder routingProtocolBuilder, + @Nonnull final ReadContext readContext) throws ReadFailedException { + + final RoutingProtocolKey key = instanceIdentifier.firstKeyOf(RoutingProtocol.class); + routingProtocolBuilder.setName(key.getName()).setKey(key).setType(Static.class) + .addAugmentation(RoutingProtocolStateVppAttr.class, new RoutingProtocolStateVppAttrBuilder() + .setVppProtocolStateAttributes(new VppProtocolStateAttributesBuilder() + .setPrimaryVrf(new VniReference(Long.valueOf(routingProtocolContext + .getIndex(key.getName(), readContext.getMappingContext())))) + .build()) + .build()); + } +} diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingStateCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingStateCustomizer.java new file mode 100644 index 000000000..5a6b23b7d --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingStateCustomizer.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016 Cisco 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.read; + +import io.fd.hc2vpp.routing.write.Ipv4WriteRoutingNodes; +import io.fd.hc2vpp.routing.write.Ipv6WriteRoutingNodes; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.Routing; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.RoutingBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.RoutingState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.RoutingStateBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.StandardRoutingInstance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.RoutingInstance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.RoutingInstanceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.RoutingProtocols; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.RoutingProtocolsBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocol; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocolBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol.StaticRoutes; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol.StaticRoutesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.RoutingProtocolStateVppAttr; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.RoutingProtocolVppAttr; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.RoutingProtocolVppAttrBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.routing.routing.instance.routing.protocols.routing.protocol.VppProtocolAttributesBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RoutingStateCustomizer + implements InitializingReaderCustomizer<RoutingState, RoutingStateBuilder>, Ipv4WriteRoutingNodes { + + private static final Logger LOG = LoggerFactory.getLogger(RoutingStateCustomizer.class); + + private static RoutingInstance mapRoutingInstances( + final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.RoutingInstance state) { + return new RoutingInstanceBuilder() + .setName(state.getName()) + .setEnabled(true) + .setRouterId(state.getRouterId()) + .setType(StandardRoutingInstance.class) + .setRoutingProtocols(RoutingStateCustomizer.mapRoutingProtocols(state.getRoutingProtocols())) + .build(); + } + + private static RoutingProtocols mapRoutingProtocols( + final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.RoutingProtocols state) { + + if (state != null) { + return new RoutingProtocolsBuilder() + .setRoutingProtocol(state.getRoutingProtocol() != null + ? RoutingStateCustomizer.mapRoutingProtocol(state.getRoutingProtocol()) + : null) + .build(); + } else { + return null; + } + } + + private static List<RoutingProtocol> mapRoutingProtocol( + final List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.RoutingProtocol> state) { + return state.stream() + .map(routingProtocol -> new RoutingProtocolBuilder() + .setName(routingProtocol.getName()) + .setEnabled(true) + .setType(routingProtocol.getType()) + .setStaticRoutes(RoutingStateCustomizer.mapStaticRoutes(routingProtocol.getStaticRoutes())) + .addAugmentation(RoutingProtocolVppAttr.class, + mapVppAttr(routingProtocol.getAugmentation(RoutingProtocolStateVppAttr.class))) + .build()) + .collect(Collectors.toList()); + } + + private static RoutingProtocolVppAttr mapVppAttr(final RoutingProtocolStateVppAttr attrState) { + return new RoutingProtocolVppAttrBuilder() + .setVppProtocolAttributes(attrState.getVppProtocolStateAttributes() == null + ? null + : + new VppProtocolAttributesBuilder() + .setPrimaryVrf(attrState.getVppProtocolStateAttributes().getPrimaryVrf()) + .build()) + .build(); + } + + private static StaticRoutes mapStaticRoutes( + final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol.StaticRoutes state) { + return new StaticRoutesBuilder() + .addAugmentation(CONFIG_IPV4_AUG_CLASS, + Ipv4WriteRoutingNodes.INSTANCE.mapIpv4Augmentation(state.getAugmentation(STATE_IPV4_AUG_CLASS))) + .addAugmentation(Ipv6WriteRoutingNodes.CONFIG_IPV6_AUG_CLASS, + Ipv6WriteRoutingNodes.INSTANCE.mapIpv6Augmentation(state.getAugmentation( + Ipv6WriteRoutingNodes.STATE_IPV6_AUG_CLASS))) + .build(); + } + + @Nonnull + @Override + public RoutingStateBuilder getBuilder(@Nonnull final InstanceIdentifier<RoutingState> instanceIdentifier) { + return new RoutingStateBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<RoutingState> instanceIdentifier, + @Nonnull final RoutingStateBuilder routingStateBuilder, + @Nonnull final ReadContext readContext) throws ReadFailedException { + // does nothing + LOG.info("Reading {}", instanceIdentifier); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final RoutingState routingState) { + //Routing state is root + } + + @Nonnull + @Override + public Initialized<? extends DataObject> init(@Nonnull final InstanceIdentifier<RoutingState> id, + @Nonnull final RoutingState readValue, + @Nonnull final ReadContext ctx) { + + return Initialized.create(InstanceIdentifier.create(Routing.class), new RoutingBuilder() + .setRoutingInstance(readValue.getRoutingInstance() + .stream() + .map(routingInstance -> mapRoutingInstances(routingInstance)) + .collect(Collectors.toList())) + .build()); + } +} diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingStateReaderFactory.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingStateReaderFactory.java new file mode 100644 index 000000000..c26de124e --- /dev/null +++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/read/RoutingStateReaderFactory.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016 Cisco 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.read; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.common.translate.util.MultiNamingContext; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.routing.RoutingConfiguration; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.impl.read.GenericReader; +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.IpFibDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.RoutingState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.RoutingInstance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.RoutingProtocols; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.RoutingProtocolsBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.RoutingProtocol; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol.StaticRoutes; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.state.routing.instance.routing.protocols.routing.protocol.StaticRoutesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.RoutingProtocolStateVppAttr; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.routing.state.routing.instance.routing.protocols.routing.protocol.VppProtocolStateAttributes; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Factory producing readers for routing plugin's data. + */ +public final class RoutingStateReaderFactory implements ReaderFactory, Ipv4ReadRoutingNodes, Ipv6ReadRoutingNodes { + + private static final InstanceIdentifier<RoutingState> ROOT_STATE_CONTAINER_ID = + InstanceIdentifier.create(RoutingState.class); + + @Inject + private RoutingConfiguration configuration; + + @Inject + @Named("interface-context") + private NamingContext interfaceContext; + + @Inject + @Named(RoutingConfiguration.ROUTING_PROTOCOL_CONTEXT) + private NamingContext routingProtocolContext; + + @Inject + @Named(RoutingConfiguration.ROUTE_CONTEXT) + private NamingContext routeContext; + + @Inject + @Named(RoutingConfiguration.ROUTE_HOP_CONTEXT) + private MultiNamingContext routeHopContext; + + @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); + + final InstanceIdentifier<RoutingInstance> routingInstanceInstanceIdentifier = + routingInstanceIdentifier(ROOT_STATE_CONTAINER_ID); + final InstanceIdentifier<RoutingProtocols> routingProtocolsInstanceIdentifier = + routingProtocolsId(routingInstanceInstanceIdentifier); + final InstanceIdentifier<RoutingProtocol> routingProtocolInstanceIdentifier = + routingProtocolInstanceIdentifier(routingProtocolsInstanceIdentifier); + final InstanceIdentifier<StaticRoutes> staticRoutesInstanceIdentifier = + staticRoutesInstanceIdentifier(routingProtocolInstanceIdentifier); + + // RoutingState + registry.add(new GenericReader<>(ROOT_STATE_CONTAINER_ID, new RoutingStateCustomizer())); + // RoutingInstance + registry.add(new GenericListReader<>(routingInstanceInstanceIdentifier, + new RoutingInstanceCustomizer(configuration))); + + // RoutingProtocols + registry.addStructuralReader(routingProtocolsInstanceIdentifier, RoutingProtocolsBuilder.class); + + // RoutingProtocol + registry.subtreeAdd(routingProtocolHandledChildren(), new GenericListReader<>(routingProtocolInstanceIdentifier, + new RoutingProtocolCustomizer(routingProtocolContext, ipv4DumpManager, ipv6DumpManager))); + + // StaticRoutes + registry.addStructuralReader(staticRoutesInstanceIdentifier, StaticRoutesBuilder.class); + + registerIpv4Routes(staticRoutesInstanceIdentifier, registry, ipv4DumpManager, configuration, routeHopContext, + interfaceContext, routeContext, routingProtocolContext); + registerIpv6Routes(staticRoutesInstanceIdentifier, registry, ipv6DumpManager, configuration, routeHopContext, + interfaceContext, routeContext, routingProtocolContext); + } + + private static ImmutableSet<InstanceIdentifier<?>> routingProtocolHandledChildren() { + return ImmutableSet + .of(InstanceIdentifier.create(RoutingProtocol.class).augmentation(RoutingProtocolStateVppAttr.class) + .child(VppProtocolStateAttributes.class)); + } + + private InstanceIdentifier<StaticRoutes> staticRoutesInstanceIdentifier( + final InstanceIdentifier<RoutingProtocol> routingProtocolInstanceIdentifier) { + return routingProtocolInstanceIdentifier.child(StaticRoutes.class); + } + + private InstanceIdentifier<RoutingProtocol> routingProtocolInstanceIdentifier( + final InstanceIdentifier<RoutingProtocols> routingProtocolsInstanceIdentifier) { + return routingProtocolsInstanceIdentifier.child(RoutingProtocol.class); + } + + private InstanceIdentifier<RoutingProtocols> routingProtocolsId( + final InstanceIdentifier<RoutingInstance> routingInstanceInstanceIdentifier) { + return routingInstanceInstanceIdentifier.child(RoutingProtocols.class); + } + + private InstanceIdentifier<RoutingInstance> routingInstanceIdentifier( + final InstanceIdentifier<RoutingState> routingStateId) { + return routingStateId.child(RoutingInstance.class); + } +} |