diff options
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip')
14 files changed, 948 insertions, 199 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/IpReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/IpReader.java new file mode 100644 index 000000000..c16bde1ca --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/IpReader.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017 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.v3po.interfacesstate.ip; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.IfaceDumpFilter; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.util.read.cache.DumpSupplier; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.vpp.jvpp.core.dto.IpAddressDetails; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.IpAddressDump; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetails; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.IpNeighborDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone; +import org.opendaylight.yangtools.yang.binding.Identifier; + +/** + * Utility class providing Ipv4/6 read support. + */ +public interface IpReader extends AddressTranslator, JvppReplyConsumer { + + @Nonnull + default <T extends Identifier> List<T> getAllIpv4AddressIds( + final Optional<IpAddressDetailsReplyDump> dumpOptional, + @Nonnull final Function<Ipv4AddressNoZone, T> keyConstructor) { + if (dumpOptional.isPresent() && dumpOptional.get().ipAddressDetails != null) { + return dumpOptional.get().ipAddressDetails.stream() + .map(detail -> keyConstructor.apply(arrayToIpv4AddressNoZone(detail.ip))) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + @Nonnull + default <T extends Identifier> List<T> getAllIpv6AddressIds( + final Optional<IpAddressDetailsReplyDump> dumpOptional, + @Nonnull final Function<Ipv6AddressNoZone, T> keyConstructor) { + if (dumpOptional.isPresent() && dumpOptional.get().ipAddressDetails != null) { + return dumpOptional.get().ipAddressDetails.stream() + .map(detail -> keyConstructor.apply(arrayToIpv6AddressNoZone(detail.ip))) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + default Optional<IpAddressDetails> findIpv4AddressDetailsByIp( + final Optional<IpAddressDetailsReplyDump> dump, + @Nonnull final Ipv4AddressNoZone ip) { + checkNotNull(ip, "ip address should not be null"); + + if (dump.isPresent() && dump.get().ipAddressDetails != null) { + final List<IpAddressDetails> details = dump.get().ipAddressDetails; + + return Optional.of(details.stream() + .filter(singleDetail -> ip.equals(arrayToIpv4AddressNoZone(singleDetail.ip))) + .collect(RWUtils.singleItemCollector())); + } + return Optional.absent(); + } + + default Optional<IpAddressDetails> findIpv6AddressDetailsByIp( + final Optional<IpAddressDetailsReplyDump> dump, + @Nonnull final Ipv6AddressNoZone ip) { + checkNotNull(ip, "ip address should not be null"); + + if (dump.isPresent() && dump.get().ipAddressDetails != null) { + final List<IpAddressDetails> details = dump.get().ipAddressDetails; + + return Optional.of(details.stream() + .filter(singleDetail -> ip.equals(arrayToIpv6AddressNoZone(singleDetail.ip))) + .collect(RWUtils.singleItemCollector())); + } + return Optional.absent(); + } + + default EntityDumpExecutor<IpAddressDetailsReplyDump, IfaceDumpFilter> createAddressDumpExecutor( + @Nonnull final FutureJVppCore vppApi) { + return (identifier, params) -> { + checkNotNull(params, "Address dump params cannot be null"); + + final IpAddressDump dumpRequest = new IpAddressDump(); + dumpRequest.isIpv6 = booleanToByte(params.isIpv6()); + dumpRequest.swIfIndex = params.getInterfaceIndex(); + + return getReplyForRead(vppApi.ipAddressDump(dumpRequest).toCompletableFuture(), identifier); + }; + } + + default EntityDumpExecutor<IpNeighborDetailsReplyDump, IfaceDumpFilter> createNeighbourDumpExecutor( + @Nonnull final FutureJVppCore vppApi) { + return (identifier, params) -> { + checkNotNull(params, "Address dump params cannot be null"); + + final IpNeighborDump dumpRequest = new IpNeighborDump(); + dumpRequest.isIpv6 = booleanToByte(params.isIpv6()); + dumpRequest.swIfIndex = params.getInterfaceIndex(); + + return getReplyForRead(vppApi.ipNeighborDump(dumpRequest).toCompletableFuture(), identifier); + }; + } + + @Nonnull + default <T extends Identifier> List<T> getNeighborKeys( + final DumpSupplier<Optional<IpNeighborDetailsReplyDump>> dumpSupplier, + final Function<IpNeighborDetails, T> detailToKey) + throws ReadFailedException { + final Optional<IpNeighborDetailsReplyDump> neighbourDumpOpt = dumpSupplier.get(); + + if (neighbourDumpOpt.isPresent()) { + final IpNeighborDetailsReplyDump neighbourDump = neighbourDumpOpt.get(); + + return neighbourDump.ipNeighborDetails.stream() + .map(detailToKey) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java deleted file mode 100644 index a32f8f20c..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.v3po.interfacesstate.ip; - -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.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -import java.util.List; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborKey; -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; - -/** - * Operational data read operation customizer for {@link Neighbor}<br> - * Currently not supported in jvpp, so this is only dummy implementation<br> - */ -public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer<Neighbor, NeighborKey, NeighborBuilder> { - - private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); - - public Ipv4NeighbourCustomizer(FutureJVppCore futureJVppCore) { - super(futureJVppCore); - } - - @Override - public NeighborBuilder getBuilder(InstanceIdentifier<Neighbor> id) { - return new NeighborBuilder(); - } - - @Override - public void readCurrentAttributes(InstanceIdentifier<Neighbor> id, NeighborBuilder builder, ReadContext ctx) - throws ReadFailedException { - //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first + implement init - LOG.warn("Operation not supported"); - } - - @Override - public List<NeighborKey> getAllIds(InstanceIdentifier<Neighbor> id, ReadContext context) - throws ReadFailedException { - //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first - LOG.warn("Operation not supported,returning empty List"); - return Collections.emptyList(); - } - - @Override - public void merge(Builder<? extends DataObject> builder, List<Neighbor> readData) { - ((Ipv4Builder) builder).setNeighbor(readData); - } -}
\ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java deleted file mode 100644 index 8c8299dbd..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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.v3po.interfacesstate.ip; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import io.fd.hc2vpp.common.translate.util.Ipv4Translator; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.AddressDumpParams; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; -import io.fd.vpp.jvpp.core.dto.IpAddressDetails; -import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.IpAddressDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yangtools.yang.binding.Identifier; - -/** - * Utility class providing Ipv4 read support. - */ -interface Ipv4Reader extends Ipv4Translator, JvppReplyConsumer { - - @Nonnull - default <T extends Identifier> List<T> getAllIpv4AddressIds( - final Optional<IpAddressDetailsReplyDump> dumpOptional, - @Nonnull final Function<Ipv4AddressNoZone, T> keyConstructor) { - if (dumpOptional.isPresent() && dumpOptional.get().ipAddressDetails != null) { - return dumpOptional.get().ipAddressDetails.stream() - .map(detail -> keyConstructor.apply(arrayToIpv4AddressNoZone(detail.ip))) - .collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - } - - default Optional<IpAddressDetails> findIpAddressDetailsByIp( - final Optional<IpAddressDetailsReplyDump> dump, - @Nonnull final Ipv4AddressNoZone ip) { - checkNotNull(ip, "ip address should not be null"); - - if (dump.isPresent() && dump.get().ipAddressDetails != null) { - final List<IpAddressDetails> details = dump.get().ipAddressDetails; - - return Optional.of(details.stream() - .filter(singleDetail -> ip.equals(arrayToIpv4AddressNoZone(singleDetail.ip))) - .collect(RWUtils.singleItemCollector())); - } - return Optional.absent(); - } - - default EntityDumpExecutor<IpAddressDetailsReplyDump, AddressDumpParams> createExecutor( - @Nonnull final FutureJVppCore vppApi) { - return (identifier, params) -> { - checkNotNull(params, "Address dump params cannot be null"); - - final IpAddressDump dumpRequest = new IpAddressDump(); - dumpRequest.isIpv6 = booleanToByte(params.isIpv6()); - dumpRequest.swIfIndex = params.getInterfaceIndex(); - - return getReplyForRead(vppApi.ipAddressDump(dumpRequest).toCompletableFuture(), identifier); - }; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/IfaceDumpFilter.java index cb80893be..19a3ed7f9 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/IfaceDumpFilter.java @@ -16,12 +16,12 @@ package io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params; -public class AddressDumpParams { +public class IfaceDumpFilter { private final int interfaceIndex; private final boolean isIpv6; - public AddressDumpParams(final int interfaceIndex, final boolean isIpv6) { + public IfaceDumpFilter(final int interfaceIndex, final boolean isIpv6) { this.interfaceIndex = interfaceIndex; this.isIpv6 = isIpv6; } @@ -36,7 +36,7 @@ public class AddressDumpParams { @Override public String toString() { - return "AddressDumpParams{" + + return "IfaceDumpFilter{" + "interfaceIndex=" + interfaceIndex + ", isIpv6=" + isIpv6 + '}'; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/Ipv4AddressCustomizer.java index a3e12faea..8b84cfa24 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/Ipv4AddressCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.fd.hc2vpp.v3po.interfacesstate.ip; +package io.fd.hc2vpp.v3po.interfacesstate.ip.v4; import static com.google.common.base.Preconditions.checkNotNull; @@ -24,7 +24,8 @@ import com.google.common.collect.ImmutableSet; import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer; -import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.AddressDumpParams; +import io.fd.hc2vpp.v3po.interfacesstate.ip.IpReader; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.IfaceDumpFilter; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; @@ -56,21 +57,20 @@ import org.slf4j.LoggerFactory; * Read customizer for interface Ipv4 addresses. */ public class Ipv4AddressCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer<Address, AddressKey, AddressBuilder>, Ipv4Reader { + implements InitializingListReaderCustomizer<Address, AddressKey, AddressBuilder>, IpReader { private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressCustomizer.class); - private static final String CACHE_KEY = Ipv4AddressCustomizer.class.getName(); private final NamingContext interfaceContext; - private final DumpCacheManager<IpAddressDetailsReplyDump, AddressDumpParams> dumpManager; + private final DumpCacheManager<IpAddressDetailsReplyDump, IfaceDumpFilter> dumpManager; public Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext) { super(futureJVppCore); this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); this.dumpManager = - new DumpCacheManager.DumpCacheManagerBuilder<IpAddressDetailsReplyDump, AddressDumpParams>() - .withExecutor(createExecutor(futureJVppCore)) + new DumpCacheManager.DumpCacheManagerBuilder<IpAddressDetailsReplyDump, IfaceDumpFilter>() + .withExecutor(createAddressDumpExecutor(futureJVppCore)) // Key needs to contain interface ID to distinguish dumps between interfaces .withCacheKeyFactory(new TypeAwareIdentifierCacheKeyFactory(IpAddressDetailsReplyDump.class, ImmutableSet.of(Interface.class))) @@ -92,13 +92,13 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer final String interfaceName = id.firstKeyOf(Interface.class).getName(); final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); final Optional<IpAddressDetailsReplyDump> dumpOptional = - dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); + dumpManager.getDump(id, ctx.getModificationCache(), new IfaceDumpFilter(interfaceIndex, false)); if (!dumpOptional.isPresent() || dumpOptional.get().ipAddressDetails.isEmpty()) { return; } final Optional<IpAddressDetails> ipAddressDetails = - findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); + findIpv4AddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); if (ipAddressDetails.isPresent()) { final IpAddressDetails detail = ipAddressDetails.get(); @@ -120,7 +120,7 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer final String interfaceName = id.firstKeyOf(Interface.class).getName(); final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); final Optional<IpAddressDetailsReplyDump> dumpOptional = - dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); + dumpManager.getDump(id, ctx.getModificationCache(), new IfaceDumpFilter(interfaceIndex, false)); return getAllIpv4AddressIds(dumpOptional, AddressKey::new); } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/Ipv4Customizer.java index 316f8ec47..ef8813ae5 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/Ipv4Customizer.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package io.fd.hc2vpp.v3po.interfacesstate.ip; +package io.fd.hc2vpp.v3po.interfacesstate.ip.v4; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +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.ip.rev140616.Interface2Builder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; @@ -27,7 +28,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061 import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/Ipv4NeighbourCustomizer.java new file mode 100644 index 000000000..0e5fb310f --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/Ipv4NeighbourCustomizer.java @@ -0,0 +1,123 @@ +/* + * 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.v3po.interfacesstate.ip.v4; + +import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.NeighborOrigin.Dynamic; +import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.NeighborOrigin.Static; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.ip.IpReader; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.IfaceDumpFilter; +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.honeycomb.translate.util.read.cache.DumpCacheManager.DumpCacheManagerBuilder; +import io.fd.honeycomb.translate.util.read.cache.DumpSupplier; +import io.fd.honeycomb.translate.util.read.cache.TypeAwareIdentifierCacheKeyFactory; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetails; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.function.Function; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Operational data read operation customizer for {@link Neighbor}<br> + * Currently not supported in jvpp, so this is only dummy implementation<br> + */ +public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<Neighbor, NeighborKey, NeighborBuilder>, IpReader { + + private final DumpCacheManager<IpNeighborDetailsReplyDump, IfaceDumpFilter> dumpManager; + private final NamingContext interfaceContext; + + public Ipv4NeighbourCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + dumpManager = new DumpCacheManagerBuilder<IpNeighborDetailsReplyDump, IfaceDumpFilter>() + .withExecutor(createNeighbourDumpExecutor(futureJVppCore)) + // cached with parent interface scope + .withCacheKeyFactory(new TypeAwareIdentifierCacheKeyFactory(IpNeighborDetailsReplyDump.class, + ImmutableSet.of(Interface.class))) + .build(); + this.interfaceContext = interfaceContext; + } + + @Override + public NeighborBuilder getBuilder(InstanceIdentifier<Neighbor> id) { + return new NeighborBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<Neighbor> id, NeighborBuilder builder, ReadContext ctx) + throws ReadFailedException { + + final Ipv4AddressNoZone ip = id.firstKeyOf(Neighbor.class).getIp(); + + final Optional<IpNeighborDetailsReplyDump> dumpOpt = dumpSupplier(id, ctx).get(); + + if (dumpOpt.isPresent()) { + dumpOpt.get().ipNeighborDetails + .stream() + .filter(ipNeighborDetails -> ip.equals(arrayToIpv4AddressNoZone(ipNeighborDetails.ipAddress))) + .findFirst() + .ifPresent(ipNeighborDetails -> builder.setIp(arrayToIpv4AddressNoZone(ipNeighborDetails.ipAddress)) + .setKey(keyMapper().apply(ipNeighborDetails)) + .setLinkLayerAddress(toPhysAddress(ipNeighborDetails.macAddress)) + .setOrigin(ipNeighborDetails.isStatic == 0 + ? Dynamic + : Static)); + } + } + + @Override + public List<NeighborKey> getAllIds(InstanceIdentifier<Neighbor> id, ReadContext context) + throws ReadFailedException { + return getNeighborKeys(dumpSupplier(id, context), keyMapper()); + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<Neighbor> readData) { + ((Ipv4Builder) builder).setNeighbor(readData); + } + + private Function<IpNeighborDetails, NeighborKey> keyMapper() { + return ipNeighborDetails -> new NeighborKey(arrayToIpv4AddressNoZone(ipNeighborDetails.ipAddress)); + } + + private DumpSupplier<Optional<IpNeighborDetailsReplyDump>> dumpSupplier(final InstanceIdentifier<Neighbor> id, + final ReadContext context) { + return () -> dumpManager + .getDump(id, context.getModificationCache(), new IfaceDumpFilter(interfaceContext + .getIndex(id.firstKeyOf(Interface.class).getName(), context.getMappingContext()), + false)); + } + +}
\ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/subinterface/SubInterfaceIpv4AddressCustomizer.java index a8617c578..f27229acd 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/subinterface/SubInterfaceIpv4AddressCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.fd.hc2vpp.v3po.interfacesstate.ip; +package io.fd.hc2vpp.v3po.interfacesstate.ip.v4.subinterface; import static com.google.common.base.Preconditions.checkNotNull; @@ -23,7 +23,8 @@ import com.google.common.collect.ImmutableSet; import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer; -import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.AddressDumpParams; +import io.fd.hc2vpp.v3po.interfacesstate.ip.IpReader; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.IfaceDumpFilter; import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; @@ -55,19 +56,19 @@ import org.slf4j.LoggerFactory; * Read customizer for sub-interface Ipv4 addresses. */ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer<Address, AddressKey, AddressBuilder>, Ipv4Reader { + implements InitializingListReaderCustomizer<Address, AddressKey, AddressBuilder>, IpReader { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class); private final NamingContext interfaceContext; - private final DumpCacheManager<IpAddressDetailsReplyDump, AddressDumpParams> dumpManager; + private final DumpCacheManager<IpAddressDetailsReplyDump, IfaceDumpFilter> dumpManager; public SubInterfaceIpv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext) { super(futureJVppCore); this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<IpAddressDetailsReplyDump, AddressDumpParams>() - .withExecutor(createExecutor(futureJVppCore)) + this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<IpAddressDetailsReplyDump, IfaceDumpFilter>() + .withExecutor(createAddressDumpExecutor(futureJVppCore)) //same as with ipv4 addresses for interfaces, these must have cache scope of their parent sub-interface .withCacheKeyFactory(new TypeAwareIdentifierCacheKeyFactory(IpAddressDetailsReplyDump.class, ImmutableSet.of(SubInterface.class))) @@ -94,15 +95,15 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); final Optional<IpAddressDetailsReplyDump> dumpOptional = dumpManager - .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); + .getDump(id, ctx.getModificationCache(), new IfaceDumpFilter(subInterfaceIndex, false)); final Optional<IpAddressDetails> ipAddressDetails = - findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); + findIpv4AddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); if (ipAddressDetails.isPresent()) { final IpAddressDetails detail = ipAddressDetails.get(); builder.setIp(arrayToIpv4AddressNoZone(detail.ip)); - builder.setSubnet(new PrefixLengthBuilder().setPrefixLength(Short.valueOf(detail.prefixLength)).build()); + builder.setSubnet(new PrefixLengthBuilder().setPrefixLength((short) detail.prefixLength).build()); if (LOG.isDebugEnabled()) { LOG.debug("Attributes for {} sub-interface (id={}) address {} successfully read: {}", @@ -112,6 +113,7 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer } @Override + @Nonnull public List<AddressKey> getAllIds(@Nonnull InstanceIdentifier<Address> id, @Nonnull ReadContext ctx) throws ReadFailedException { LOG.debug("Reading list of keys for sub-interface addresses: {}", id); @@ -119,7 +121,7 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); final Optional<IpAddressDetailsReplyDump> dumpOptional = dumpManager - .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); + .getDump(id, ctx.getModificationCache(), new IfaceDumpFilter(subInterfaceIndex, false)); return getAllIpv4AddressIds(dumpOptional, AddressKey::new); } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/subinterface/SubInterfaceIpv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/subinterface/SubInterfaceIpv4NeighbourCustomizer.java new file mode 100644 index 000000000..71833db0d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v4/subinterface/SubInterfaceIpv4NeighbourCustomizer.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017 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.v3po.interfacesstate.ip.v4.subinterface; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.ip.IpReader; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.IfaceDumpFilter; +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.honeycomb.translate.util.read.cache.DumpCacheManager.DumpCacheManagerBuilder; +import io.fd.honeycomb.translate.util.read.cache.DumpSupplier; +import io.fd.honeycomb.translate.util.read.cache.TypeAwareIdentifierCacheKeyFactory; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetails; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.function.Function; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.NeighborBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.NeighborKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceIpv4NeighbourCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<Neighbor, NeighborKey, NeighborBuilder>, IpReader { + + private final DumpCacheManager<IpNeighborDetailsReplyDump, IfaceDumpFilter> dumpManager; + private final NamingContext interfaceContext; + + public SubInterfaceIpv4NeighbourCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + dumpManager = new DumpCacheManagerBuilder<IpNeighborDetailsReplyDump, IfaceDumpFilter>() + .withExecutor(createNeighbourDumpExecutor(futureJVppCore)) + // cached with parent interface scope + .withCacheKeyFactory(new TypeAwareIdentifierCacheKeyFactory(IpNeighborDetailsReplyDump.class, + ImmutableSet.of(Interface.class))) + .build(); + this.interfaceContext = interfaceContext; + } + + @Override + public NeighborBuilder getBuilder(InstanceIdentifier<Neighbor> id) { + return new NeighborBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<Neighbor> id, NeighborBuilder builder, ReadContext ctx) + throws ReadFailedException { + + final Ipv4AddressNoZone ip = id.firstKeyOf(Neighbor.class).getIp(); + + final Optional<IpNeighborDetailsReplyDump> dumpOpt = dumpSupplier(id, ctx).get(); + + if (dumpOpt.isPresent()) { + dumpOpt.get().ipNeighborDetails + .stream() + .filter(ipNeighborDetails -> ip.equals(arrayToIpv4AddressNoZone(ipNeighborDetails.ipAddress))) + .findFirst() + .ifPresent(ipNeighborDetails -> builder.setIp(arrayToIpv4AddressNoZone(ipNeighborDetails.ipAddress)) + .setKey(keyMapper().apply(ipNeighborDetails)) + .setLinkLayerAddress(toPhysAddress(ipNeighborDetails.macAddress))); + } + } + + @Override + public List<NeighborKey> getAllIds(InstanceIdentifier<Neighbor> id, ReadContext context) + throws ReadFailedException { + return getNeighborKeys(dumpSupplier(id, context), keyMapper()); + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<Neighbor> readData) { + ((Ipv4Builder) builder).setNeighbor(readData); + } + + private Function<IpNeighborDetails, NeighborKey> keyMapper() { + return ipNeighborDetails -> new NeighborKey(arrayToIpv4AddressNoZone(ipNeighborDetails.ipAddress)); + } + + private DumpSupplier<Optional<IpNeighborDetailsReplyDump>> dumpSupplier(final InstanceIdentifier<Neighbor> id, + final ReadContext context) { + return () -> dumpManager + .getDump(id, context.getModificationCache(), new IfaceDumpFilter(interfaceContext + .getIndex(id.firstKeyOf(Interface.class).getName(), context.getMappingContext()), + false)); + } + +}
\ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/Ipv6AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/Ipv6AddressCustomizer.java new file mode 100644 index 000000000..a5166525e --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/Ipv6AddressCustomizer.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2017 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.v3po.interfacesstate.ip.v6; + + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.ip.IpReader; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.IfaceDumpFilter; +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.InitializingListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.TypeAwareIdentifierCacheKeyFactory; +import io.fd.vpp.jvpp.core.dto.IpAddressDetails; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv6.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv6.AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv6.AddressKey; +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 Ipv6AddressCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer<Address, AddressKey, AddressBuilder>, IpReader { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv6AddressCustomizer.class); + + private final NamingContext interfaceContext; + private final DumpCacheManager<IpAddressDetailsReplyDump, IfaceDumpFilter> dumpManager; + + public Ipv6AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder<IpAddressDetailsReplyDump, IfaceDumpFilter>() + .withExecutor(createAddressDumpExecutor(futureJVppCore)) + // Key needs to contain interface ID to distinguish dumps between interfaces + .withCacheKeyFactory(new TypeAwareIdentifierCacheKeyFactory(IpAddressDetailsReplyDump.class, + ImmutableSet.of(Interface.class))) + .build(); + } + + @Override + @Nonnull + public AddressBuilder getBuilder(@Nonnull InstanceIdentifier<Address> id) { + return new AddressBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull InstanceIdentifier<Address> id, @Nonnull AddressBuilder builder, + @Nonnull ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes for interface address: {}", id); + + final String interfaceName = id.firstKeyOf(Interface.class).getName(); + final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); + final Optional<IpAddressDetailsReplyDump> dumpOptional = + dumpManager.getDump(id, ctx.getModificationCache(), new IfaceDumpFilter(interfaceIndex, true)); + + if (!dumpOptional.isPresent() || dumpOptional.get().ipAddressDetails.isEmpty()) { + return; + } + final Optional<IpAddressDetails> ipAddressDetails = + findIpv6AddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); + + if (ipAddressDetails.isPresent()) { + final IpAddressDetails detail = ipAddressDetails.get(); + builder.setIp(arrayToIpv6AddressNoZone(detail.ip)) + .setPrefixLength((short) Byte.toUnsignedInt(detail.prefixLength)) + .build(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Attributes for {} interface (id={}) address {} successfully read: {}", + interfaceName, interfaceIndex, id, builder.build()); + } + } + } + + @Override + public List<AddressKey> getAllIds(@Nonnull InstanceIdentifier<Address> id, @Nonnull ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading list of keys for interface addresses: {}", id); + + final String interfaceName = id.firstKeyOf(Interface.class).getName(); + final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); + final Optional<IpAddressDetailsReplyDump> dumpOptional = + dumpManager.getDump(id, ctx.getModificationCache(), new IfaceDumpFilter(interfaceIndex, true)); + + return getAllIpv6AddressIds(dumpOptional, AddressKey::new); + } + + @Override + public void merge(@Nonnull Builder<? extends DataObject> builder, @Nonnull List<Address> readData) { + ((Ipv6Builder) builder).setAddress(readData); + } + + @Override + public Initialized<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.Address> init( + @Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.AddressBuilder() + .setIp(readValue.getIp()) + .setPrefixLength(readValue.getPrefixLength()) + .build()); + } + + static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.Address> getCfgId( + final InstanceIdentifier<Address> id) { + return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(Interface1.class) + .child(Ipv6.class) + .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.Address.class, + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.AddressKey( + id.firstKeyOf(Address.class).getIp())); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/Ipv6Customizer.java index 97f223a8c..8f12619fd 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/Ipv6Customizer.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package io.fd.hc2vpp.v3po.interfacesstate.ip; +package io.fd.hc2vpp.v3po.interfacesstate.ip.v6; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; +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.ip.rev140616.Interface2Builder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6; @@ -28,15 +28,15 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061 import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Ipv6Customizer extends FutureJVppCustomizer implements ReaderCustomizer<Ipv6, Ipv6Builder> { - private final NamingContext interfaceContext; + private static final Logger LOG = LoggerFactory.getLogger(Ipv6Customizer.class); - public Ipv6Customizer(@Nonnull final FutureJVppCore futureJVppCore, final NamingContext interfaceContext) { + public Ipv6Customizer(@Nonnull final FutureJVppCore futureJVppCore) { super(futureJVppCore); - this.interfaceContext = interfaceContext; } @Override @@ -53,14 +53,6 @@ public class Ipv6Customizer extends FutureJVppCustomizer implements ReaderCustom @Override public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6> id, @Nonnull final Ipv6Builder builder, @Nonnull final ReadContext ctx) throws ReadFailedException { - // TODO HONEYCOMB-102 implement + init -// final IpAddressDump dumpRequest = new IpAddressDump(); -// dumpRequest.isIpv6 = 1; -// dumpRequest.swIfIndex = interfaceContext.getIndex(id.firstKeyOf(Interface.class).getName(), -// ctx.getMappingContext()); -// final CompletionStage<IpAddressDetailsReplyDump> addressDumpFuture = getFutureJVpp(). -// ipAddressDump(dumpRequest); -// final IpAddressDetailsReplyDump reply = TranslateUtils.getReply(addressDumpFuture.toCompletableFuture()); + LOG.debug("Reading Ipv6 leaves (mtu, forwarding) is not supported by VPP API"); } - } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/Ipv6NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/Ipv6NeighbourCustomizer.java new file mode 100644 index 000000000..923795f50 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/Ipv6NeighbourCustomizer.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2017 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.v3po.interfacesstate.ip.v6; + + +import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.NeighborOrigin.Dynamic; +import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.NeighborOrigin.Static; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.ip.IpReader; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.IfaceDumpFilter; +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.honeycomb.translate.util.read.cache.DumpSupplier; +import io.fd.honeycomb.translate.util.read.cache.TypeAwareIdentifierCacheKeyFactory; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetails; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.function.Function; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv6.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv6.NeighborBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv6.NeighborKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class Ipv6NeighbourCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<Neighbor, NeighborKey, NeighborBuilder>, IpReader { + + + private final DumpCacheManager<IpNeighborDetailsReplyDump, IfaceDumpFilter> dumpManager; + private final NamingContext interfaceContext; + + public Ipv6NeighbourCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<IpNeighborDetailsReplyDump, IfaceDumpFilter>() + .withExecutor(createNeighbourDumpExecutor(futureJVppCore)) + // cached with parent interface scope + .withCacheKeyFactory(new TypeAwareIdentifierCacheKeyFactory(IpNeighborDetailsReplyDump.class, + ImmutableSet.of(Interface.class))) + .build(); + this.interfaceContext = interfaceContext; + } + + @Override + public NeighborBuilder getBuilder(InstanceIdentifier<Neighbor> id) { + return new NeighborBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<Neighbor> id, NeighborBuilder builder, ReadContext ctx) + throws ReadFailedException { + + final Ipv6AddressNoZone ip = id.firstKeyOf(Neighbor.class).getIp(); + + final Optional<IpNeighborDetailsReplyDump> dumpOpt = dumpSupplier(id, ctx).get(); + + if (dumpOpt.isPresent()) { + dumpOpt.get().ipNeighborDetails + .stream() + .filter(ipNeighborDetails -> ip.equals(arrayToIpv6AddressNoZone(ipNeighborDetails.ipAddress))) + .findFirst() + .ifPresent(ipNeighborDetails -> builder.setIp(arrayToIpv6AddressNoZone(ipNeighborDetails.ipAddress)) + .setKey(keyMapper().apply(ipNeighborDetails)) + .setLinkLayerAddress(toPhysAddress(ipNeighborDetails.macAddress)) + .setOrigin(ipNeighborDetails.isStatic == 0 + ? Dynamic + : Static)); + } + } + + @Override + public List<NeighborKey> getAllIds(InstanceIdentifier<Neighbor> id, ReadContext context) + throws ReadFailedException { + return getNeighborKeys(dumpSupplier(id, context), keyMapper()); + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<Neighbor> readData) { + ((Ipv6Builder) builder).setNeighbor(readData); + } + + private Function<IpNeighborDetails, NeighborKey> keyMapper() { + return ipNeighborDetails -> new NeighborKey(arrayToIpv6AddressNoZone(ipNeighborDetails.ipAddress)); + } + + private DumpSupplier<Optional<IpNeighborDetailsReplyDump>> dumpSupplier(final InstanceIdentifier<Neighbor> id, + final ReadContext context) { + return () -> dumpManager + .getDump(id, context.getModificationCache(), new IfaceDumpFilter(interfaceContext + .getIndex(id.firstKeyOf(Interface.class).getName(), context.getMappingContext()), + true)); + } +}
\ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/subinterface/SubInterfaceIpv6AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/subinterface/SubInterfaceIpv6AddressCustomizer.java new file mode 100644 index 000000000..4aea4c00e --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/subinterface/SubInterfaceIpv6AddressCustomizer.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2017 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.v3po.interfacesstate.ip.v6.subinterface; + + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.ip.IpReader; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.IfaceDumpFilter; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +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.InitializingListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.TypeAwareIdentifierCacheKeyFactory; +import io.fd.vpp.jvpp.core.dto.IpAddressDetails; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.Ipv6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.AddressKey; +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 SubInterfaceIpv6AddressCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer<Address, AddressKey, AddressBuilder>, IpReader { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv6AddressCustomizer.class); + + private final NamingContext interfaceContext; + private final DumpCacheManager<IpAddressDetailsReplyDump, IfaceDumpFilter> dumpManager; + + public SubInterfaceIpv6AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<IpAddressDetailsReplyDump, IfaceDumpFilter>() + .withExecutor(createAddressDumpExecutor(futureJVppCore)) + .withCacheKeyFactory(new TypeAwareIdentifierCacheKeyFactory(IpAddressDetailsReplyDump.class, + ImmutableSet.of(SubInterface.class))) + .build(); + } + + private static String getSubInterfaceName(@Nonnull final InstanceIdentifier<Address> id) { + return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), + Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier())); + } + + @Override + @Nonnull + public AddressBuilder getBuilder(@Nonnull InstanceIdentifier<Address> id) { + return new AddressBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull InstanceIdentifier<Address> id, @Nonnull AddressBuilder builder, + @Nonnull ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes for sub-interface address: {}", id); + + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); + final Optional<IpAddressDetailsReplyDump> dumpOptional = dumpManager + .getDump(id, ctx.getModificationCache(), new IfaceDumpFilter(subInterfaceIndex, false)); + + final Optional<IpAddressDetails> ipAddressDetails = + findIpv6AddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); + + if (ipAddressDetails.isPresent()) { + final IpAddressDetails detail = ipAddressDetails.get(); + builder.setIp(arrayToIpv6AddressNoZone(detail.ip)); + builder.setPrefixLength((short) detail.prefixLength); + + if (LOG.isDebugEnabled()) { + LOG.debug("Attributes for {} sub-interface (id={}) address {} successfully read: {}", + subInterfaceName, subInterfaceIndex, id, builder.build()); + } + } + } + + @Override + @Nonnull + public List<AddressKey> getAllIds(@Nonnull InstanceIdentifier<Address> id, @Nonnull ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading list of keys for sub-interface addresses: {}", id); + + final String subInterfaceName = getSubInterfaceName(id); + final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); + final Optional<IpAddressDetailsReplyDump> dumpOptional = dumpManager + .getDump(id, ctx.getModificationCache(), new IfaceDumpFilter(subInterfaceIndex, false)); + + return getAllIpv6AddressIds(dumpOptional, AddressKey::new); + } + + @Override + public void merge(@Nonnull Builder<? extends DataObject> builder, @Nonnull List<Address> readData) { + ((Ipv6Builder) builder).setAddress(readData); + } + + @Override + @Nonnull + public Initialized<Address> init( + @Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), readValue); + } + + private InstanceIdentifier<Address> getCfgId(final InstanceIdentifier<Address> id) { + return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) + .child(Ipv6.class) + .child(Address.class, new AddressKey(id.firstKeyOf(Address.class))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/subinterface/SubInterfaceIpv6NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/subinterface/SubInterfaceIpv6NeighbourCustomizer.java new file mode 100644 index 000000000..ac7882729 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/v6/subinterface/SubInterfaceIpv6NeighbourCustomizer.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017 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.v3po.interfacesstate.ip.v6.subinterface; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.ip.IpReader; +import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.IfaceDumpFilter; +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.honeycomb.translate.util.read.cache.DumpCacheManager.DumpCacheManagerBuilder; +import io.fd.honeycomb.translate.util.read.cache.DumpSupplier; +import io.fd.honeycomb.translate.util.read.cache.TypeAwareIdentifierCacheKeyFactory; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetails; +import io.fd.vpp.jvpp.core.dto.IpNeighborDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.function.Function; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.Neighbor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.NeighborBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.NeighborKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceIpv6NeighbourCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<Neighbor, NeighborKey, NeighborBuilder>, IpReader { + + private final DumpCacheManager<IpNeighborDetailsReplyDump, IfaceDumpFilter> dumpManager; + private final NamingContext interfaceContext; + + public SubInterfaceIpv6NeighbourCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + dumpManager = new DumpCacheManagerBuilder<IpNeighborDetailsReplyDump, IfaceDumpFilter>() + .withExecutor(createNeighbourDumpExecutor(futureJVppCore)) + // cached with parent interface scope + .withCacheKeyFactory(new TypeAwareIdentifierCacheKeyFactory(IpNeighborDetailsReplyDump.class, + ImmutableSet.of(Interface.class))) + .build(); + this.interfaceContext = interfaceContext; + } + + @Override + public NeighborBuilder getBuilder(InstanceIdentifier<Neighbor> id) { + return new NeighborBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<Neighbor> id, NeighborBuilder builder, ReadContext ctx) + throws ReadFailedException { + + final Ipv6AddressNoZone ip = id.firstKeyOf(Neighbor.class).getIp(); + + final Optional<IpNeighborDetailsReplyDump> dumpOpt = dumpSupplier(id, ctx).get(); + + if (dumpOpt.isPresent()) { + dumpOpt.get().ipNeighborDetails + .stream() + .filter(ipNeighborDetails -> ip.equals(arrayToIpv6AddressNoZone(ipNeighborDetails.ipAddress))) + .findFirst() + .ifPresent(ipNeighborDetails -> builder.setIp(arrayToIpv6AddressNoZone(ipNeighborDetails.ipAddress)) + .setKey(keyMapper().apply(ipNeighborDetails)) + .setLinkLayerAddress(toPhysAddress(ipNeighborDetails.macAddress))); + } + } + + @Override + public List<NeighborKey> getAllIds(InstanceIdentifier<Neighbor> id, ReadContext context) + throws ReadFailedException { + return getNeighborKeys(dumpSupplier(id, context), keyMapper()); + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<Neighbor> readData) { + ((Ipv6Builder) builder).setNeighbor(readData); + } + + private Function<IpNeighborDetails, NeighborKey> keyMapper() { + return ipNeighborDetails -> new NeighborKey(arrayToIpv6AddressNoZone(ipNeighborDetails.ipAddress)); + } + + private DumpSupplier<Optional<IpNeighborDetailsReplyDump>> dumpSupplier(final InstanceIdentifier<Neighbor> id, + final ReadContext context) { + return () -> dumpManager + .getDump(id, context.getModificationCache(), new IfaceDumpFilter(interfaceContext + .getIndex(id.firstKeyOf(Interface.class).getName(), context.getMappingContext()), + true)); + } + +}
\ No newline at end of file |