diff options
author | 2016-11-09 08:55:04 +0100 | |
---|---|---|
committer | 2016-11-09 08:55:04 +0100 | |
commit | ddb7683677ef0bcc291f686dbed9c95d50c4046b (patch) | |
tree | 3315c21c9e4cba0bb6c25c7c5ec0048bb51458e5 /lisp/lisp2vpp/src/main/java/io/fd | |
parent | 64d4c13102024ab8f1e0215c6a6a4894c3306c56 (diff) |
HONEYCOMB-254 - Adjacencies dump support
Added mapping context between adjacency id(HC side)
and combination of remote and local eids(vpp side)
Change-Id: Icbba9130a82b7af51b23e6d6d68fcfbf49e66c99
Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
Diffstat (limited to 'lisp/lisp2vpp/src/main/java/io/fd')
11 files changed, 463 insertions, 30 deletions
diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/LispModule.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/LispModule.java index bd345904f..db5557f0d 100644 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/LispModule.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/LispModule.java @@ -27,6 +27,7 @@ import com.google.inject.Singleton; import com.google.inject.multibindings.Multibinder; import com.google.inject.name.Names; import io.fd.honeycomb.lisp.cfgattrs.LispConfiguration; +import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext; import io.fd.honeycomb.lisp.context.util.ContextsReaderFactoryProvider; import io.fd.honeycomb.lisp.context.util.EidMappingContext; import io.fd.honeycomb.lisp.translate.read.factory.LispStateReaderFactory; @@ -63,6 +64,11 @@ public class LispModule extends AbstractModule { .annotatedWith(Names.named(REMOTE_MAPPING_CONTEXT)) .toInstance(new EidMappingContext(REMOTE_MAPPING_CONTEXT)); + LOG.info("Binding Adjacencies context"); + bind(AdjacenciesMappingContext.class) + .annotatedWith(Names.named(LispConfiguration.ADJACENCIES_IDENTIFICATION_CONTEXT)) + .toInstance(new AdjacenciesMappingContext(LispConfiguration.ADJACENCIES_IDENTIFICATION_CONTEXT)); + LOG.info("Binding reader factories"); final Multibinder<ReaderFactory> readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); readerFactoryBinder.addBinding().to(LispStateReaderFactory.class); diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/cfgattrs/LispConfiguration.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/cfgattrs/LispConfiguration.java index 75083468c..177f650c9 100644 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/cfgattrs/LispConfiguration.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/cfgattrs/LispConfiguration.java @@ -48,12 +48,12 @@ public class LispConfiguration { public static final String REMOTE_MAPPING_CONTEXT = "remote-mapping-context"; /** - * Central honeycomb initializer. - */ - public static final String HONEYCOMB_INITIALIZER = "honeycomb-initializer"; - - /** * Unique prefix for naming context of locator sets. **/ public static final String LOCATOR_SET_CONTEXT_PREFIX = "locator-set-"; + + /** + * Adjacency id to eid pair mapping + * */ + public static final String ADJACENCIES_IDENTIFICATION_CONTEXT = "adjacencies-identification-context"; } diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/context/util/AdjacenciesMappingContext.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/context/util/AdjacenciesMappingContext.java new file mode 100644 index 000000000..557dc2771 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/context/util/AdjacenciesMappingContext.java @@ -0,0 +1,174 @@ +/* + * 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.honeycomb.lisp.context.util; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.util.RWUtils; +import java.util.stream.Collector; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.AdjacenciesIdentificationContexts; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.AdjacenciesIdentification; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.AdjacenciesIdentificationKey; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.Mappings; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.Mapping; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.MappingBuilder; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.MappingKey; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPair; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPairBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MappingId; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +public class AdjacenciesMappingContext { + + private static final Collector<Mapping, ?, Mapping> SINGLE_ITEM_COLLECTOR = RWUtils.singleItemCollector(); + + private final KeyedInstanceIdentifier<AdjacenciesIdentification, AdjacenciesIdentificationKey> + namingContextIid; + + /** + * Create new naming context + * + * @param instanceName name of this context instance. Will be used as list item identifier within context data tree + */ + public AdjacenciesMappingContext(@Nonnull final String instanceName) { + namingContextIid = InstanceIdentifier.create(AdjacenciesIdentificationContexts.class).child( + AdjacenciesIdentification.class, new AdjacenciesIdentificationKey(instanceName)); + } + + /** + * Retrieve name for mapping stored provided mappingContext instance. + * + * @param localEidId {@code MappingId} for local eid + * @param remoteEidId {@code MappingId} for remote eid + * @param mappingContext mapping context providing context data for current transaction + * @return name mapped to provided index + */ + @Nonnull + public synchronized String getAdjacencyId( + @Nonnull final String localEidId, + @Nonnull final String remoteEidId, + @Nonnull final MappingContext mappingContext) { + + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + checkState(read.isPresent(), "No adjacencies mappings stored"); + + return read.get().getMapping().stream() + .filter(mapping -> isSame(pairForCombination(localEidId, remoteEidId), mapping)) + .collect(SINGLE_ITEM_COLLECTOR).getId(); + } + + private boolean isSame(final EidIdentificatorPair currentPair, final Mapping mapping) { + // EidIdentificatorPair is container so it needs to be compared like this + final EidIdentificatorPair mappingPair = mapping.getEidIdentificatorPair(); + return currentPair.getLocalEidId().equals(mappingPair.getLocalEidId()) + && currentPair.getRemoteEidId().equals(mappingPair.getRemoteEidId()); + } + + private EidIdentificatorPair pairForCombination(final @Nonnull String localEidId, + final @Nonnull String remoteEidId) { + return new EidIdentificatorPairBuilder() + .setLocalEidId(new MappingId(localEidId)) + .setRemoteEidId(new MappingId(remoteEidId)) + .build(); + } + + /** + * Check whether mapping is present for index. + * + * @param localEidId {@code MappingId} for local eid + * @param remoteEidId {@code MappingId} for remote eid + * @param mappingContext mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + public synchronized boolean containsId( + @Nonnull final String localEidId, + @Nonnull final String remoteEidId, + @Nonnull final MappingContext mappingContext) { + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + + return read.isPresent() && + read.get().getMapping() + .stream() + .anyMatch(mapping -> isSame(pairForCombination(localEidId, remoteEidId), mapping)); + } + + /** + * Add mapping to current context + * + * @param index index of a mapped item + * @param localEidId {@code MappingId} for local eid + * @param remoteEidId {@code MappingId} for remote eid + * @param mappingContext mapping context providing context data for current transaction + */ + public synchronized void addEidPair( + @Nonnull final String index, + @Nonnull final String localEidId, + @Nonnull final String remoteEidId, + final MappingContext mappingContext) { + + final KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid = getMappingIid(index); + mappingContext.put(mappingIid, new MappingBuilder().setId(index).setEidIdentificatorPair( + pairForCombination(localEidId, remoteEidId)).build()); + } + + private KeyedInstanceIdentifier<Mapping, MappingKey> getMappingIid(final String index) { + return namingContextIid.child(Mappings.class).child(Mapping.class, new MappingKey(index)); + } + + + /** + * Remove mapping from current context + * + * @param index identificator of a mapped item + * @param mappingContext mapping context providing context data for current transaction + */ + public synchronized void removeForIndex(@Nonnull final String index, final MappingContext mappingContext) { + mappingContext.delete(getMappingIid(index)); + } + + /** + * Returns index value associated with the given name. + * + * @param index index whitch should value sits on + * @param mappingContext mapping context providing context data for current transaction + * @return integer index value matching supplied name + * @throws IllegalArgumentException if name was not found + */ + public synchronized EidIdentificatorPair getEidPair(@Nonnull final String index, + final MappingContext mappingContext) { + final Optional<Mapping> read = mappingContext.read(getMappingIid(index)); + checkArgument(read.isPresent(), "No mapping stored for index: %s", index); + return read.get().getEidIdentificatorPair(); + } + + /** + * Check whether mapping is present for name. + * + * @param index index of a mapped item + * @param mappingContext mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + public synchronized boolean containsEidPairForIndex(@Nonnull final String index, + @Nonnull final MappingContext mappingContext) { + return mappingContext.read(getMappingIid(index)).isPresent(); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizer.java index 0764880ff..d7003c802 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizer.java @@ -17,29 +17,64 @@ package io.fd.honeycomb.lisp.translate.read; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams; +import io.fd.honeycomb.lisp.translate.util.EidTranslator; +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.RWUtils; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.LispAdjacenciesGet; +import io.fd.vpp.jvpp.core.dto.LispAdjacenciesGetReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import io.fd.vpp.jvpp.core.types.LispAdjacency; +import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import javax.annotation.Nonnull; -import javax.naming.OperationNotSupportedException; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPair; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPairBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MappingId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.AdjacenciesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.Adjacency; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.AdjacencyBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.AdjacencyKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; 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; - public class AdjacencyCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer<Adjacency, AdjacencyKey, AdjacencyBuilder> { + implements ListReaderCustomizer<Adjacency, AdjacencyKey, AdjacencyBuilder>, JvppReplyConsumer, EidTranslator { - public AdjacencyCustomizer(@Nonnull final FutureJVppCore futureJvpp) { + private final DumpCacheManager<LispAdjacenciesGetReply, AdjacencyDumpParams> dumpCacheManager; + private final AdjacenciesMappingContext adjacenciesMappingContext; + private final EidPairProducer eidPairProducer; + + + public AdjacencyCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final EidMappingContext localMappingContext, + @Nonnull final EidMappingContext remoteMappingContext, + @Nonnull final AdjacenciesMappingContext adjacenciesMappingContext) { super(futureJvpp); + dumpCacheManager = new DumpCacheManager.DumpCacheManagerBuilder<LispAdjacenciesGetReply, AdjacencyDumpParams>() + .withExecutor(createExecutor()) + .build(); + + this.adjacenciesMappingContext = + checkNotNull(adjacenciesMappingContext, "Adjacencies mapping context cannot be null"); + this.eidPairProducer = new EidPairProducer(localMappingContext, remoteMappingContext); } @Nonnull @@ -47,6 +82,22 @@ public class AdjacencyCustomizer extends FutureJVppCustomizer public List<AdjacencyKey> getAllIds(@Nonnull final InstanceIdentifier<Adjacency> id, @Nonnull final ReadContext context) throws ReadFailedException { + final int vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue(); + + final Optional<LispAdjacenciesGetReply> optionalDump = + dumpCacheManager.getDump(id, context.getModificationCache(), new AdjacencyDumpParams(vni)); + + + if (optionalDump.isPresent()) { + return Arrays.stream(optionalDump.get().adjacencies) + .map(lispAdjacency -> eidPairProducer.createPair(lispAdjacency, vni, context.getMappingContext())) + .map(pair -> adjacenciesMappingContext + .getAdjacencyId(pair.getLocalEidId().getValue(), pair.getRemoteEidId().getValue(), + context.getMappingContext())) + .map(AdjacencyKey::new) + .collect(Collectors.toList()); + } + //does not throw exception to not disturb lisp state reading return Collections.emptyList(); } @@ -66,7 +117,76 @@ public class AdjacencyCustomizer extends FutureJVppCustomizer public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Adjacency> id, @Nonnull final AdjacencyBuilder builder, @Nonnull final ReadContext ctx) throws ReadFailedException { - // TODO - finish after https://jira.fd.io/browse/VPP-362 - throw new ReadFailedException(id, new OperationNotSupportedException("Operation not supported")); + + final int vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue(); + + final Optional<LispAdjacenciesGetReply> optionalDump = dumpCacheManager + .getDump(id, ctx.getModificationCache(), new AdjacencyDumpParams(vni)); + + if (!optionalDump.isPresent() || optionalDump.get().adjacencies.length == 0) { + return; + } + + final String currentAdjacencyId = id.firstKeyOf(Adjacency.class).getId(); + final EidIdentificatorPair currentAdjacencyIdentificationPair = + adjacenciesMappingContext.getEidPair(currentAdjacencyId, ctx.getMappingContext()); + + final LispAdjacency currentAdjacency = Arrays.stream(optionalDump.get().adjacencies) + .filter(lispAdjacency -> Objects.equals(currentAdjacencyIdentificationPair, + eidPairProducer.createPair(lispAdjacency, vni, ctx.getMappingContext()))) + .collect(RWUtils.singleItemCollector()); + + builder.setId(currentAdjacencyId) + .setKey(new AdjacencyKey(currentAdjacencyId)) + .setLocalEid(getArrayAsLocalEid( + MappingsDumpParams.EidType.valueOf(currentAdjacency.eidType), currentAdjacency.leid, vni)) + .setRemoteEid(getArrayAsRemoteEid( + MappingsDumpParams.EidType.valueOf(currentAdjacency.eidType), currentAdjacency.reid, vni)); + } + + private EntityDumpExecutor<LispAdjacenciesGetReply, AdjacencyDumpParams> createExecutor() { + return (final InstanceIdentifier<?> identifier, final AdjacencyDumpParams params) -> { + checkNotNull(params, "Dump parameters cannot be null"); + + final LispAdjacenciesGet request = new LispAdjacenciesGet(); + request.vni = params.getVni(); + + return getReplyForRead(getFutureJVpp().lispAdjacenciesGet(request).toCompletableFuture(), identifier); + }; + } + + private class EidPairProducer implements EidTranslator { + + private final EidMappingContext localMappingContext; + private final EidMappingContext remoteMappingContext; + + public EidPairProducer(final EidMappingContext localMappingContext, + final EidMappingContext remoteMappingContext) { + this.localMappingContext = checkNotNull(localMappingContext, "Local mapping context cannot be null"); + this.remoteMappingContext = checkNotNull(remoteMappingContext, "Remote mapping context cannot be null"); + } + + public EidIdentificatorPair createPair(final LispAdjacency data, final int vni, + final MappingContext mappingContext) { + return new EidIdentificatorPairBuilder() + .setLocalEidId(new MappingId(localMappingContext.getId(getArrayAsEidLocal( + MappingsDumpParams.EidType.valueOf(data.eidType), data.leid, vni), mappingContext))) + .setRemoteEidId(new MappingId(remoteMappingContext.getId(getArrayAsEidLocal( + MappingsDumpParams.EidType.valueOf(data.eidType), data.reid, vni), mappingContext))) + .build(); + } + } + + private static final class AdjacencyDumpParams { + + private final int vni; + + AdjacencyDumpParams(final int vni) { + this.vni = vni; + } + + public int getVni() { + return this.vni; + } } } diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/EidTableReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/EidTableReaderFactory.java index dad04bff5..553b5b548 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/EidTableReaderFactory.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/EidTableReaderFactory.java @@ -17,7 +17,10 @@ package io.fd.honeycomb.lisp.translate.read.factory; +import static com.google.common.base.Preconditions.checkNotNull; + import com.google.common.collect.ImmutableSet; +import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext; import io.fd.honeycomb.lisp.context.util.EidMappingContext; import io.fd.honeycomb.lisp.translate.read.AdjacencyCustomizer; import io.fd.honeycomb.lisp.translate.read.BridgeDomainSubtableCustomizer; @@ -61,15 +64,19 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; */ final class EidTableReaderFactory extends AbstractLispReaderFactoryBase implements ReaderFactory { + private final AdjacenciesMappingContext adjacenciesMappingContext; + private EidTableReaderFactory(final InstanceIdentifier<LispState> lispStateId, final FutureJVppCore vppApi, final NamingContext interfaceContext, final NamingContext locatorSetContext, final NamingContext bridgeDomainContext, final EidMappingContext localMappingContext, - final EidMappingContext remoteMappingContext) { + final EidMappingContext remoteMappingContext, + final AdjacenciesMappingContext adjacenciesMappingContext) { super(lispStateId, vppApi, interfaceContext, locatorSetContext, bridgeDomainContext, localMappingContext, remoteMappingContext); + this.adjacenciesMappingContext = checkNotNull(adjacenciesMappingContext, "Adjacencies context cannot be null"); } public static EidTableReaderFactory newInstance(@Nonnull final InstanceIdentifier<LispState> lispStateId, @@ -78,10 +85,10 @@ final class EidTableReaderFactory extends AbstractLispReaderFactoryBase implemen @Nonnull final NamingContext locatorSetContext, @Nonnull final NamingContext bridgeDomainContext, @Nonnull final EidMappingContext localMappingContext, - @Nonnull final EidMappingContext remoteMappingContext) { + @Nonnull final EidMappingContext remoteMappingContext, + @Nonnull final AdjacenciesMappingContext adjacenciesMappingContext) { return new EidTableReaderFactory(lispStateId, vppApi, interfaceContext, locatorSetContext, bridgeDomainContext, - localMappingContext, - remoteMappingContext); + localMappingContext, remoteMappingContext, adjacenciesMappingContext); } @Override @@ -165,10 +172,12 @@ final class EidTableReaderFactory extends AbstractLispReaderFactoryBase implemen registry.subtreeAdd( ImmutableSet.of(adjacencySubtreeId.child(LocalEid.class), adjacencySubtreeId.child(RemoteEid.class)), new GenericListReader<>(vrfTableAdjacenciesInstanceIdentifier.child(Adjacency.class), - new AdjacencyCustomizer(vppApi))); + new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext, + adjacenciesMappingContext))); registry.subtreeAdd( ImmutableSet.of(adjacencySubtreeId.child(LocalEid.class), adjacencySubtreeId.child(RemoteEid.class)), new GenericListReader<>(bridgeDomainAdjacenciesInstanceIdentifier.child(Adjacency.class), - new AdjacencyCustomizer(vppApi))); + new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext, + adjacenciesMappingContext))); } } diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LispStateReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LispStateReaderFactory.java index 4f7ed0f02..e96246b43 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LispStateReaderFactory.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LispStateReaderFactory.java @@ -16,6 +16,8 @@ package io.fd.honeycomb.lisp.translate.read.factory; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.ADJACENCIES_IDENTIFICATION_CONTEXT; import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.INTERFACE_CONTEXT; import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCAL_MAPPING_CONTEXT; import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT; @@ -23,6 +25,7 @@ import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.REMOTE_MAPPING_CON import com.google.inject.Inject; import com.google.inject.name.Named; +import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext; import io.fd.honeycomb.lisp.context.util.EidMappingContext; import io.fd.honeycomb.lisp.translate.read.LispStateCustomizer; import io.fd.honeycomb.lisp.translate.read.PitrCfgCustomizer; @@ -44,15 +47,21 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; */ public class LispStateReaderFactory extends AbstractLispReaderFactoryBase implements ReaderFactory { + private final AdjacenciesMappingContext adjacenciesIdentificationContext; + @Inject public LispStateReaderFactory(final FutureJVppCore vppApi, @Named(INTERFACE_CONTEXT) final NamingContext interfaceContext, @Named(LOCATOR_SET_CONTEXT) final NamingContext locatorSetContext, @Named("bridge-domain-context") final NamingContext bridgeDomainContext, @Named(LOCAL_MAPPING_CONTEXT) final EidMappingContext localMappingContext, - @Named(REMOTE_MAPPING_CONTEXT) final EidMappingContext remoteMappingContext) { + @Named(REMOTE_MAPPING_CONTEXT) final EidMappingContext remoteMappingContext, + @Named(ADJACENCIES_IDENTIFICATION_CONTEXT) final + AdjacenciesMappingContext adjacenciesIdentificationContext) { super(InstanceIdentifier.create(LispState.class), vppApi, interfaceContext, locatorSetContext, bridgeDomainContext, localMappingContext, remoteMappingContext); + this.adjacenciesIdentificationContext = + checkNotNull(adjacenciesIdentificationContext, "Adjacencies mapping context cannot be null"); } @Override @@ -65,7 +74,7 @@ public class LispStateReaderFactory extends AbstractLispReaderFactoryBase implem MapResolversReaderFactory.newInstance(lispStateId, vppApi).init(registry); EidTableReaderFactory .newInstance(lispStateId, vppApi, interfaceContext, locatorSetContext, bridgeDomainContext, - localMappingContext, remoteMappingContext) + localMappingContext, remoteMappingContext, adjacenciesIdentificationContext) .init(registry); registry.add(new GenericReader<>(lispStateId.child(LispFeatureData.class).child(PitrCfg.class), diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidMetadataProvider.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidMetadataProvider.java index 960f0697a..88571f717 100644 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidMetadataProvider.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidMetadataProvider.java @@ -19,6 +19,8 @@ package io.fd.honeycomb.lisp.translate.util; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.LocalEidBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.RemoteEidBuilder; /** * Trait providing metadata for eid's @@ -49,4 +51,18 @@ public interface EidMetadataProvider { .setVirtualNetworkId(new InstanceIdType(Long.valueOf(vni))); } + default LocalEidBuilder newEidBuilderLocal(@Nonnull final Class<? extends LispAddressFamily> eidAddressType, + final int vni) { + return new LocalEidBuilder() + .setAddressType(eidAddressType) + .setVirtualNetworkId(new InstanceIdType(Long.valueOf(vni))); + } + + default RemoteEidBuilder newEidBuilderRemote(@Nonnull final Class<? extends LispAddressFamily> eidAddressType, + final int vni) { + return new RemoteEidBuilder() + .setAddressType(eidAddressType) + .setVirtualNetworkId(new InstanceIdType(Long.valueOf(vni))); + } + } diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidTranslator.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidTranslator.java index c508e59d3..0b7faba31 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidTranslator.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidTranslator.java @@ -141,6 +141,62 @@ public interface EidTranslator extends AddressTranslator, EidMetadataProvider { } } + default LocalEid getArrayAsLocalEid(@Nonnull final EidType type, final byte[] address, final int vni) { + switch (type) { + case IPV4: { + return newEidBuilderLocal(Ipv4Afi.class, vni) + .setAddress( + new Ipv4Builder().setIpv4(arrayToIpv4AddressNoZoneReversed(address)) + .build()) + .build(); + } + case IPV6: { + return newEidBuilderLocal(Ipv6Afi.class, vni) + .setAddress( + new Ipv6Builder().setIpv6(arrayToIpv6AddressNoZoneReversed(address)) + .build()) + .build(); + } + case MAC: { + return newEidBuilderLocal(MacAfi.class, vni) + .setAddress( + new MacBuilder().setMac(new MacAddress(byteArrayToMacSeparated(address))) + .build()).build(); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + + default RemoteEid getArrayAsRemoteEid(@Nonnull final EidType type, final byte[] address, final int vni) { + switch (type) { + case IPV4: { + return newEidBuilderRemote(Ipv4Afi.class, vni) + .setAddress( + new Ipv4Builder().setIpv4(arrayToIpv4AddressNoZoneReversed(address)) + .build()) + .build(); + } + case IPV6: { + return newEidBuilderRemote(Ipv6Afi.class, vni) + .setAddress( + new Ipv6Builder().setIpv6(arrayToIpv6AddressNoZoneReversed(address)) + .build()) + .build(); + } + case MAC: { + return newEidBuilderRemote(MacAfi.class, vni) + .setAddress( + new MacBuilder().setMac(new MacAddress(byteArrayToMacSeparated(address))) + .build()).build(); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + default String getArrayAsEidString( EidType type, byte[] address) { switch (type) { diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizer.java index 6ec631f5c..b394f2a69 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizer.java @@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType; +import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext; import io.fd.honeycomb.lisp.context.util.EidMappingContext; import io.fd.honeycomb.lisp.translate.util.EidTranslator; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; @@ -47,27 +48,49 @@ public class AdjacencyCustomizer extends FutureJVppCustomizer private final EidMappingContext localEidsMappingContext; private final EidMappingContext remoteEidsMappingContext; + private final AdjacenciesMappingContext adjacenciesMappingContext; public AdjacencyCustomizer(@Nonnull final FutureJVppCore futureJvpp, - @Nonnull EidMappingContext localEidsMappingContext, - @Nonnull EidMappingContext remoteEidsMappingContext) { + @Nonnull final EidMappingContext localEidsMappingContext, + @Nonnull final EidMappingContext remoteEidsMappingContext, + @Nonnull final AdjacenciesMappingContext adjacenciesMappingContext) { super(futureJvpp); this.localEidsMappingContext = checkNotNull(localEidsMappingContext, "Eid context for local eid's cannot be null"); this.remoteEidsMappingContext = checkNotNull(remoteEidsMappingContext, "Eid context for remote eid's cannot be null"); + this.adjacenciesMappingContext = checkNotNull(adjacenciesMappingContext, "Adjacencies context cannot be null"); } @Override public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Adjacency> id, @Nonnull final Adjacency dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException { - try { addDelAdjacency(true, id, dataAfter, writeContext); } catch (TimeoutException | VppBaseCallException e) { throw new WriteFailedException.CreateFailedException(id, dataAfter, e); } + + //after successful creation, create mapping + adjacenciesMappingContext.addEidPair(adjacencyId(id), + localEidId(dataAfter, writeContext), + remoteEidId(dataAfter, writeContext), + writeContext.getMappingContext()); + } + + private String remoteEidId(final @Nonnull Adjacency dataAfter, final @Nonnull WriteContext writeContext) { + return remoteEidsMappingContext.getId(toRemoteEid(dataAfter.getRemoteEid()), writeContext.getMappingContext()) + .getValue(); + } + + private String localEidId(final @Nonnull Adjacency dataAfter, final @Nonnull WriteContext writeContext) { + return localEidsMappingContext.getId(toLocalEid(dataAfter.getLocalEid()), writeContext.getMappingContext()) + .getValue(); + } + + private String adjacencyId(final @Nonnull InstanceIdentifier<Adjacency> id) { + return id.firstKeyOf(Adjacency.class).getId(); } @Override @@ -86,6 +109,10 @@ public class AdjacencyCustomizer extends FutureJVppCustomizer } catch (TimeoutException | VppBaseCallException e) { throw new WriteFailedException.CreateFailedException(id, dataBefore, e); } + + //after successful creation, create mapping + adjacenciesMappingContext.removeForIndex(adjacencyId(id), + writeContext.getMappingContext()); } private void addDelAdjacency(boolean add, final InstanceIdentifier<Adjacency> id, final Adjacency data, diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LispWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LispWriterFactory.java index 6fb0149ce..055aa72b9 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LispWriterFactory.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LispWriterFactory.java @@ -18,6 +18,7 @@ package io.fd.honeycomb.lisp.translate.write.factory; import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.ADJACENCIES_IDENTIFICATION_CONTEXT; import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.INTERFACE_CONTEXT; import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCAL_MAPPING_CONTEXT; import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT; @@ -25,6 +26,7 @@ import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.REMOTE_MAPPING_CON import com.google.inject.Inject; import com.google.inject.name.Named; +import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext; import io.fd.honeycomb.lisp.context.util.EidMappingContext; import io.fd.honeycomb.lisp.translate.write.LispCustomizer; import io.fd.honeycomb.lisp.translate.write.PitrCfgCustomizer; @@ -46,6 +48,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class LispWriterFactory extends AbstractLispWriterFactoryBase implements WriterFactory { private final NamingContext bridgeDomainContext; + private final AdjacenciesMappingContext adjacenciesMappingContext; @Inject public LispWriterFactory(final FutureJVppCore vppApi, @@ -53,10 +56,13 @@ public final class LispWriterFactory extends AbstractLispWriterFactoryBase imple @Named(LOCATOR_SET_CONTEXT) final NamingContext locatorSetContext, @Named("bridge-domain-context") final NamingContext bridgeDomainContext, @Named(LOCAL_MAPPING_CONTEXT) final EidMappingContext localMappingContext, - @Named(REMOTE_MAPPING_CONTEXT) final EidMappingContext remoteMappingContext) { + @Named(REMOTE_MAPPING_CONTEXT) final EidMappingContext remoteMappingContext, + @Named(ADJACENCIES_IDENTIFICATION_CONTEXT) final AdjacenciesMappingContext adjacenciesMappingContext) { super(InstanceIdentifier.create(Lisp.class), vppApi, interfaceContext, locatorSetContext, localMappingContext, remoteMappingContext); this.bridgeDomainContext = checkNotNull(bridgeDomainContext, "Bridge domain context cannot be null"); + this.adjacenciesMappingContext = + checkNotNull(adjacenciesMappingContext, "Adjacencies mapping context cannot be null"); } @Override @@ -64,7 +70,7 @@ public final class LispWriterFactory extends AbstractLispWriterFactoryBase imple registry.add(new GenericWriter<>(lispInstanceIdentifier, new LispCustomizer(vppApi))); VniTableWriterFactory.newInstance(lispInstanceIdentifier, vppApi, localMappingContext, remoteMappingContext, - bridgeDomainContext) + bridgeDomainContext, adjacenciesMappingContext) .init(registry); LocatorSetsWriterFactory.newInstance(lispInstanceIdentifier, vppApi, interfaceContext, locatorSetContext) .init(registry); diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/VniTableWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/VniTableWriterFactory.java index f13b01c97..9e9152ce0 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/VniTableWriterFactory.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/VniTableWriterFactory.java @@ -19,6 +19,7 @@ package io.fd.honeycomb.lisp.translate.write.factory; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableSet; +import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext; import io.fd.honeycomb.lisp.context.util.EidMappingContext; import io.fd.honeycomb.lisp.translate.write.AdjacencyCustomizer; import io.fd.honeycomb.lisp.translate.write.BridgeDomainSubtableCustomizer; @@ -53,20 +54,26 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +//TODO - HONEYCOMB-282 - refactor this and other factories for better readability + /** * Factory for producing writers for {@code EidTable} */ final class VniTableWriterFactory extends AbstractLispWriterFactoryBase implements WriterFactory { private final NamingContext bridgeDomainContext; + private final AdjacenciesMappingContext adjacenciesMappingContext; private VniTableWriterFactory(final InstanceIdentifier<Lisp> lispInstanceIdentifier, final FutureJVppCore vppApi, final EidMappingContext localMappingContext, final EidMappingContext remoteMappingContext, - final NamingContext bridgeDomainContext) { + final NamingContext bridgeDomainContext, + final AdjacenciesMappingContext adjacenciesMappingContext) { super(lispInstanceIdentifier, vppApi, localMappingContext, remoteMappingContext); this.bridgeDomainContext = checkNotNull(bridgeDomainContext, "Bridge domain context cannot be null"); + this.adjacenciesMappingContext = + checkNotNull(adjacenciesMappingContext, "Adjacencies mapping context cannot be null"); } public static VniTableWriterFactory newInstance( @@ -74,9 +81,10 @@ final class VniTableWriterFactory extends AbstractLispWriterFactoryBase implemen @Nonnull final FutureJVppCore vppApi, @Nonnull final EidMappingContext localMappingContext, @Nonnull final EidMappingContext remoteMappingContext, - @Nonnull final NamingContext bridgeDomainContext) { + @Nonnull final NamingContext bridgeDomainContext, + @Nonnull final AdjacenciesMappingContext adjacenciesMappingContext) { return new VniTableWriterFactory(lispInstanceIdentifier, vppApi, localMappingContext, remoteMappingContext, - bridgeDomainContext); + bridgeDomainContext, adjacenciesMappingContext); } @Override @@ -135,7 +143,8 @@ final class VniTableWriterFactory extends AbstractLispWriterFactoryBase implemen new GenericListWriter<>( vrfSubtableId.child(RemoteMappings.class).child(RemoteMapping.class) .child(Adjacencies.class).child(Adjacency.class), - new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext))); + new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext, + adjacenciesMappingContext))); //VniTable - > BridgeDomainSubtable -> RemoteMappings - > RemoteMapping - > Adjacencies - > Adjacency registry.subtreeAdd(ImmutableSet.of(adjacencySubtreeId .child(LocalEid.class), adjacencySubtreeId.child(RemoteEid.class)), @@ -143,6 +152,7 @@ final class VniTableWriterFactory extends AbstractLispWriterFactoryBase implemen bridgeDomainSubtableId.child(RemoteMappings.class) .child(RemoteMapping.class) .child(Adjacencies.class).child(Adjacency.class), - new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext))); + new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext, + adjacenciesMappingContext))); } } |