diff options
Diffstat (limited to 'lisp/lisp2vpp/src')
19 files changed, 998 insertions, 75 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))); } } diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/AdjacenciesMappingContextTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/AdjacenciesMappingContextTest.java new file mode 100644 index 000000000..4a5302ba6 --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/AdjacenciesMappingContextTest.java @@ -0,0 +1,184 @@ +/* + * 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 org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.honeycomb.test.tools.HoneycombTestRunner; +import io.fd.honeycomb.test.tools.annotations.InjectTestData; +import io.fd.honeycomb.test.tools.annotations.InjectablesProcessor; +import io.fd.honeycomb.test.tools.annotations.SchemaContextProvider; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.util.RWUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.$YangModuleInfoImpl; +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.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.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +@RunWith(HoneycombTestRunner.class) +public class AdjacenciesMappingContextTest implements InjectablesProcessor { + + private static final String PARENT_1 = "first"; + private static final String PARENT_2 = "second"; + private static final String PARENT_3 = "third"; + private static final String PARENT_4 = "fourth"; + + private static final String LOCAL_EID_ID_1 = "local-eid-1"; + private static final String LOCAL_EID_ID_2 = "local-eid-2"; + private static final String LOCAL_EID_ID_3 = "local-eid-3"; + + private static final String REMOTE_EID_ID_1 = "remote-eid-1"; + private static final String REMOTE_EID_ID_2 = "remote-eid-2"; + private static final String REMOTE_EID_ID_3 = "remote-eid-3"; + + @Mock + private MappingContext mappingContext; + + @Captor + private ArgumentCaptor<Mapping> mappingArgumentCaptor; + + @Captor + private ArgumentCaptor<KeyedInstanceIdentifier<Mapping, MappingKey>> keyedInstanceIdentifierArgumentCaptor; + + private AdjacenciesMappingContext adjacenciesMappingContext; + private KeyedInstanceIdentifier<AdjacenciesIdentification, AdjacenciesIdentificationKey> + adjacenciesMappingContextId; + + @SchemaContextProvider + public ModuleInfoBackedContext schemaContext() { + return provideSchemaContextFor(ImmutableSet.of($YangModuleInfoImpl.getInstance(), + org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.$YangModuleInfoImpl + .getInstance())); + } + + @InjectTestData(resourcePath = "/adjacencies-identification-context.json", id = "/naming-context:contexts" + + "/adjacencies-identification-context:adjacencies-identification-contexts" + + "/adjacencies-identification-context:adjacencies-identification[adjacencies-identification-context:name='context']" + + "/adjacencies-identification-context:mappings") + private Mappings mappings; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + + adjacenciesMappingContext = new AdjacenciesMappingContext("context"); + adjacenciesMappingContextId = InstanceIdentifier.create(AdjacenciesIdentificationContexts.class).child( + AdjacenciesIdentification.class, new AdjacenciesIdentificationKey("context")); + + when(mappingContext.read(adjacenciesMappingContextId.child(Mappings.class))).thenReturn(Optional.of(mappings)); + when(mappingContext.read(parentKey(PARENT_1))).thenReturn(Optional.of(filterForParent(PARENT_1))); + when(mappingContext.read(parentKey(PARENT_2))).thenReturn(Optional.of(filterForParent(PARENT_2))); + when(mappingContext.read(parentKey(PARENT_3))).thenReturn(Optional.of(filterForParent(PARENT_3))); + } + + private Mapping filterForParent(final String parent) { + return mappings.getMapping().stream() + .filter(mapping -> mapping.getId().equals(parent)) + .collect(RWUtils.singleItemCollector()); + } + + private KeyedInstanceIdentifier<Mapping, MappingKey> parentKey(final String parent) { + return adjacenciesMappingContextId.child(Mappings.class).child(Mapping.class, new MappingKey(parent)); + } + + @Test + public void getAdjacencyId() throws Exception { + assertEquals(PARENT_1, + adjacenciesMappingContext.getAdjacencyId(LOCAL_EID_ID_1, REMOTE_EID_ID_1, mappingContext)); + assertEquals(PARENT_2, + adjacenciesMappingContext.getAdjacencyId(LOCAL_EID_ID_2, REMOTE_EID_ID_2, mappingContext)); + assertEquals(PARENT_3, + adjacenciesMappingContext.getAdjacencyId(LOCAL_EID_ID_3, REMOTE_EID_ID_3, mappingContext)); + } + + @Test + public void containsId() throws Exception { + assertTrue(adjacenciesMappingContext.containsId(LOCAL_EID_ID_1, REMOTE_EID_ID_1, mappingContext)); + assertTrue(adjacenciesMappingContext.containsId(LOCAL_EID_ID_2, REMOTE_EID_ID_2, mappingContext)); + assertTrue(adjacenciesMappingContext.containsId(LOCAL_EID_ID_3, REMOTE_EID_ID_3, mappingContext)); + } + + @Test + public void addEidPair() throws Exception { + adjacenciesMappingContext.addEidPair(PARENT_4, LOCAL_EID_ID_1, REMOTE_EID_ID_3, mappingContext); + verify(mappingContext, times(1)) + .put(keyedInstanceIdentifierArgumentCaptor.capture(), mappingArgumentCaptor.capture()); + + final KeyedInstanceIdentifier<Mapping, MappingKey> key = keyedInstanceIdentifierArgumentCaptor.getValue(); + final Mapping mapping = mappingArgumentCaptor.getValue(); + + assertEquals(PARENT_4, key.getKey().getId()); + assertEquals(PARENT_4, mapping.getId()); + assertEquals(PARENT_4, mapping.getKey().getId()); + + final EidIdentificatorPair pair = mapping.getEidIdentificatorPair(); + assertEquals(LOCAL_EID_ID_1, pair.getLocalEidId().getValue()); + assertEquals(REMOTE_EID_ID_3, pair.getRemoteEidId().getValue()); + } + + @Test + public void removeForIndex() throws Exception { + adjacenciesMappingContext.removeForIndex(PARENT_1, mappingContext); + adjacenciesMappingContext.removeForIndex(PARENT_2, mappingContext); + adjacenciesMappingContext.removeForIndex(PARENT_3, mappingContext); + verify(mappingContext, times(1)).delete(parentKey(PARENT_1)); + verify(mappingContext, times(1)).delete(parentKey(PARENT_2)); + verify(mappingContext, times(1)).delete(parentKey(PARENT_3)); + } + + @Test + public void getEidPair() throws Exception { + final EidIdentificatorPair pair1 = adjacenciesMappingContext.getEidPair(PARENT_1, mappingContext); + final EidIdentificatorPair pair2 = adjacenciesMappingContext.getEidPair(PARENT_2, mappingContext); + final EidIdentificatorPair pair3 = adjacenciesMappingContext.getEidPair(PARENT_3, mappingContext); + + assertEquals(LOCAL_EID_ID_1, pair1.getLocalEidId().getValue()); + assertEquals(REMOTE_EID_ID_1, pair1.getRemoteEidId().getValue()); + assertEquals(LOCAL_EID_ID_2, pair2.getLocalEidId().getValue()); + assertEquals(REMOTE_EID_ID_2, pair2.getRemoteEidId().getValue()); + assertEquals(LOCAL_EID_ID_3, pair3.getLocalEidId().getValue()); + assertEquals(REMOTE_EID_ID_3, pair3.getRemoteEidId().getValue()); + } + + @Test + public void containsEidPairForIndex() throws Exception { + assertTrue(adjacenciesMappingContext.containsEidPairForIndex(PARENT_1, mappingContext)); + assertTrue(adjacenciesMappingContext.containsEidPairForIndex(PARENT_2, mappingContext)); + assertTrue(adjacenciesMappingContext.containsEidPairForIndex(PARENT_3, mappingContext)); + } + +}
\ No newline at end of file diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/EidMappingContextTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/EidMappingContextTest.java index 0a7dcb1bd..ccd38292e 100644 --- a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/EidMappingContextTest.java +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/EidMappingContextTest.java @@ -59,7 +59,7 @@ public class EidMappingContextTest implements EidMappingContextHelper { mappingEid = fromLocalToMappingEid(localEid); mappingId = new MappingId("mapping"); - defineMapping(mappingContext, mappingEid, mappingId, EID_MAPPING_CONTEXT_NAME); + defineEidMapping(mappingContext, mappingEid, mappingId, EID_MAPPING_CONTEXT_NAME); } @Test diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/AdjacencyData.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/AdjacencyData.java new file mode 100644 index 000000000..2ecfe175f --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/AdjacencyData.java @@ -0,0 +1,59 @@ +/* + * 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.translate; + +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.Eid; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.EidBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv4Afi; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Builder; + +public class AdjacencyData { + + public static final Long VNI = 12L; + + public static final Ipv4Address ADDRESS_ONE = new Ipv4Address("192.168.2.1"); + public static final Ipv4Address ADDRESS_TWO = new Ipv4Address("192.168.2.2"); + public static final Ipv4Address ADDRESS_THREE = new Ipv4Address("192.168.2.3"); + public static final Ipv4Address ADDRESS_FOUR = new Ipv4Address("192.168.2.4"); + + public static final Eid LOCAL_EID_ONE = new EidBuilder() + .setAddressType(Ipv4Afi.class) + .setVirtualNetworkId(new InstanceIdType(VNI)) + .setAddress(new Ipv4Builder().setIpv4(ADDRESS_ONE).build()) + .build(); + + public static final Eid LOCAL_EID_TWO = new EidBuilder() + .setAddressType(Ipv4Afi.class) + .setVirtualNetworkId(new InstanceIdType(VNI)) + .setAddress(new Ipv4Builder().setIpv4(ADDRESS_TWO).build()) + .build(); + + public static final Eid REMOTE_EID_ONE = new EidBuilder() + .setAddressType(Ipv4Afi.class) + .setVirtualNetworkId(new InstanceIdType(VNI)) + .setAddress(new Ipv4Builder().setIpv4(ADDRESS_THREE).build()) + .build(); + public static final Eid REMOTE_EID_TWO = new EidBuilder() + .setAddressType(Ipv4Afi.class) + .setVirtualNetworkId(new InstanceIdType(VNI)) + .setAddress(new Ipv4Builder().setIpv4(ADDRESS_FOUR).build()) + .build(); + + +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizerTest.java index 773c404ca..09d4d27fb 100644 --- a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizerTest.java +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizerTest.java @@ -16,21 +16,52 @@ package io.fd.honeycomb.lisp.translate.read; -import static org.junit.Assert.assertTrue; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.ADDRESS_ONE; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.ADDRESS_THREE; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.LOCAL_EID_ONE; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.LOCAL_EID_TWO; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.REMOTE_EID_ONE; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.REMOTE_EID_TWO; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; -import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.util.EidMetadataProvider; +import io.fd.honeycomb.lisp.util.AdjacencyMappingContextTestHelper; +import io.fd.honeycomb.lisp.util.EidMappingContextHelper; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; +import io.fd.vpp.jvpp.core.dto.LispAdjacenciesGetReply; +import io.fd.vpp.jvpp.core.types.LispAdjacency; +import java.util.List; import org.junit.Before; import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4; +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.Adjacencies; 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.dp.subtable.grouping.RemoteMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.EidTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -public class AdjacencyCustomizerTest extends ListReaderCustomizerTest<Adjacency, AdjacencyKey, AdjacencyBuilder> { +public class AdjacencyCustomizerTest + extends ListReaderCustomizerTest<Adjacency, AdjacencyKey, AdjacencyBuilder> + implements ByteDataTranslator, EidMetadataProvider, EidMappingContextHelper, AdjacencyMappingContextTestHelper { private InstanceIdentifier<Adjacency> identifier; @@ -40,21 +71,75 @@ public class AdjacencyCustomizerTest extends ListReaderCustomizerTest<Adjacency, @Before public void init() { - identifier = InstanceIdentifier.create(Adjacency.class); + identifier = InstanceIdentifier.create(EidTable.class) + .child(VniTable.class, new VniTableKey(2L)) + .child(BridgeDomainSubtable.class) + .child(RemoteMappings.class) + .child(RemoteMapping.class, new RemoteMappingKey(new MappingId("remote-mapping"))) + .child(Adjacencies.class) + .child(Adjacency.class, new AdjacencyKey("adj-one")); + + + mockApi(); + defineEidMapping(mappingContext, LOCAL_EID_ONE, new MappingId("local-eid-one"), "local-mapping-context"); + defineEidMapping(mappingContext, LOCAL_EID_TWO, new MappingId("local-eid-two"), "local-mapping-context"); + defineEidMapping(mappingContext, REMOTE_EID_ONE, new MappingId("remote-eid-one"), "remote-mapping-context"); + defineEidMapping(mappingContext, REMOTE_EID_TWO, new MappingId("remote-eid-two"), "remote-mapping-context"); + + defineAdjacencyMapping(mappingContext, "local-eid-one", "remote-eid-one", "adj-one", + "adjacencies-mapping-context"); + defineAdjacencyMapping(mappingContext, "local-eid-two", "remote-eid-two", "adj-two", + "adjacencies-mapping-context"); + mockApi(); } @Test public void getAllIds() throws Exception { - assertTrue(getCustomizer().getAllIds(identifier, ctx).isEmpty()); + final List<AdjacencyKey> keys = getCustomizer().getAllIds(identifier, ctx); + + assertThat(keys, hasSize(2)); + assertThat(keys, contains(new AdjacencyKey("adj-one"), new AdjacencyKey("adj-two"))); } - @Test(expected = ReadFailedException.class) + @Test public void readCurrentAttributes() throws Exception { - getCustomizer().readCurrentAttributes(identifier, new AdjacencyBuilder(), ctx); + final AdjacencyBuilder builder = new AdjacencyBuilder(); + getCustomizer().readCurrentAttributes(identifier, builder, ctx); + + assertEquals("adj-one", builder.getId()); + assertEquals(new AdjacencyKey("adj-one"), builder.getKey()); + assertEquals(ADDRESS_ONE.getValue(), Ipv4.class.cast(builder.getLocalEid().getAddress()).getIpv4().getValue()); + assertEquals(ADDRESS_THREE.getValue(), + Ipv4.class.cast(builder.getRemoteEid().getAddress()).getIpv4().getValue()); } @Override protected ReaderCustomizer<Adjacency, AdjacencyBuilder> initCustomizer() { - return new AdjacencyCustomizer(api); + return new AdjacencyCustomizer(api, new EidMappingContext("local-mapping-context"), + new EidMappingContext("remote-mapping-context"), + new AdjacenciesMappingContext("adjacencies-mapping-context")); + } + + + private void mockApi() { + LispAdjacency adjacencyOne = new LispAdjacency(); + adjacencyOne.eidType = 0; + adjacencyOne.leid = new byte[]{-64, -88, 2, 1}; + adjacencyOne.leidPrefixLen = 32; + adjacencyOne.reid = new byte[]{-64, -88, 2, 3}; + adjacencyOne.reidPrefixLen = 32; + + + LispAdjacency adjacencyTwo = new LispAdjacency(); + adjacencyTwo.eidType = 0; + adjacencyTwo.leid = new byte[]{-64, -88, 2, 2}; + adjacencyTwo.leidPrefixLen = 32; + adjacencyTwo.reid = new byte[]{-64, -88, 2, 4}; + adjacencyTwo.reidPrefixLen = 32; + + LispAdjacenciesGetReply reply = new LispAdjacenciesGetReply(); + reply.adjacencies = new LispAdjacency[]{adjacencyOne, adjacencyTwo}; + + when(api.lispAdjacenciesGet(any())).thenReturn(future(reply)); } }
\ No newline at end of file diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizerTest.java index 5be25bfe7..0b2536b85 100644 --- a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizerTest.java +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizerTest.java @@ -16,6 +16,10 @@ package io.fd.honeycomb.lisp.translate.write; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.ADDRESS_ONE; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.ADDRESS_THREE; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.LOCAL_EID_ONE; +import static io.fd.honeycomb.lisp.translate.AdjacencyData.REMOTE_EID_ONE; import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV4; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -26,8 +30,9 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.fd.honeycomb.lisp.context.util.AdjacenciesMappingContext; import io.fd.honeycomb.lisp.context.util.EidMappingContext; -import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.lisp.util.EidMappingContextHelper; import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; import io.fd.vpp.jvpp.core.dto.LispAddDelAdjacency; import io.fd.vpp.jvpp.core.dto.LispAddDelAdjacencyReply; @@ -43,30 +48,34 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.addres import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Builder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.MacBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; +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.Adjacencies; 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.adjacencies.grouping.adjacencies.adjacency.LocalEidBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.RemoteEidBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.RemoteMappings; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMappingKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.EidTable; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTableKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -public class AdjacencyCustomizerTest extends WriterCustomizerTest { +public class AdjacencyCustomizerTest extends WriterCustomizerTest implements EidMappingContextHelper { @Captor private ArgumentCaptor<LispAddDelAdjacency> requestCaptor; - @Mock private EidMappingContext localMappingContext; - @Mock private EidMappingContext remoteMappingContext; + @Mock + private AdjacenciesMappingContext adjacenciesMappingContext; + private AdjacencyCustomizer customizer; private InstanceIdentifier<Adjacency> emptyId; @@ -78,16 +87,18 @@ public class AdjacencyCustomizerTest extends WriterCustomizerTest { @Before public void init() { - customizer = new AdjacencyCustomizer(api, localMappingContext, remoteMappingContext); + localMappingContext = new EidMappingContext("local-mapping-context"); + remoteMappingContext = new EidMappingContext("remote-mapping-context"); + customizer = new AdjacencyCustomizer(api, localMappingContext, remoteMappingContext, adjacenciesMappingContext); emptyId = InstanceIdentifier.create(Adjacency.class); validId = InstanceIdentifier.create(EidTable.class) .child(VniTable.class, new VniTableKey(2L)) .child(BridgeDomainSubtable.class) .child(RemoteMappings.class) - .child(RemoteMapping.class) + .child(RemoteMapping.class, new RemoteMappingKey(new MappingId("remote-mapping"))) .child(Adjacencies.class) - .child(Adjacency.class); + .child(Adjacency.class, new AdjacencyKey("adj-one")); emptyData = new AdjacencyBuilder().build(); @@ -108,12 +119,12 @@ public class AdjacencyCustomizerTest extends WriterCustomizerTest { new LocalEidBuilder() .setVirtualNetworkId(new InstanceIdType(12L)) .setAddressType(Ipv4Afi.class) - .setAddress(new Ipv4Builder().setIpv4(new Ipv4Address("192.168.2.1")).build()) + .setAddress(new Ipv4Builder().setIpv4(ADDRESS_ONE).build()) .build()).setRemoteEid( new RemoteEidBuilder() .setVirtualNetworkId(new InstanceIdType(12L)) .setAddressType(Ipv4Afi.class) - .setAddress(new Ipv4Builder().setIpv4(new Ipv4Address("192.168.5.2")).build()).build()).build(); + .setAddress(new Ipv4Builder().setIpv4(ADDRESS_THREE).build()).build()).build(); when(api.lispAddDelAdjacency(any())).thenReturn(future(new LispAddDelAdjacencyReply())); } @@ -145,31 +156,20 @@ public class AdjacencyCustomizerTest extends WriterCustomizerTest { @Test public void writeCurrentAttributes() throws Exception { - when(localMappingContext.containsId( - any(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid.class), - any( - MappingContext.class))).thenReturn(true); - - when(remoteMappingContext.containsId( - any(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid.class), - any( - MappingContext.class))).thenReturn(true); - + defineEidMapping(mappingContext, LOCAL_EID_ONE, new MappingId("local-eid-one"), "local-mapping-context"); + defineEidMapping(mappingContext, REMOTE_EID_ONE, new MappingId("remote-eid-one"), "remote-mapping-context"); customizer.writeCurrentAttributes(validId, validData, writeContext); verify(api, times(1)).lispAddDelAdjacency(requestCaptor.capture()); - verifyRequest(requestCaptor.getValue(), 1, new byte[]{-64, -88, 2, 1}, 32, new byte[]{-64, -88, 5, 2}, + verifyRequest(requestCaptor.getValue(), 1, new byte[]{-64, -88, 2, 1}, 32, new byte[]{-64, -88, 2, 3}, 32, IPV4.getValue(), 2); + verify(adjacenciesMappingContext, times(1)) + .addEidPair("adj-one", "local-eid-one", "remote-eid-one", mappingContext); } @Test public void writeCurrentAttributesNonExistingLocalMapping() throws Exception { - when(localMappingContext.containsId( - any(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid.class), - any(MappingContext.class))).thenReturn(false); - - when(remoteMappingContext.containsId( - any(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid.class), - any(MappingContext.class))).thenReturn(true); + noEidMappingDefined(mappingContext, "local-eid-one", "local-mapping-context"); + defineEidMapping(mappingContext, REMOTE_EID_ONE, new MappingId("remote-eid-one"), "remote-mapping-context"); try { customizer.writeCurrentAttributes(validId, validData, writeContext); } catch (IllegalStateException e) { @@ -182,13 +182,9 @@ public class AdjacencyCustomizerTest extends WriterCustomizerTest { @Test public void writeCurrentAttributesNonExistingRemoteMapping() throws Exception { - when(localMappingContext.containsId( - any(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid.class), - any(MappingContext.class))).thenReturn(true); + noEidMappingDefined(mappingContext, "remote-eid-one", "remote-mapping-context"); + defineEidMapping(mappingContext, LOCAL_EID_ONE, new MappingId("local-eid-one"), "local-mapping-context"); - when(remoteMappingContext.containsId( - any(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid.class), - any(MappingContext.class))).thenReturn(false); try { customizer.writeCurrentAttributes(validId, validData, writeContext); } catch (IllegalStateException e) { @@ -225,8 +221,9 @@ public class AdjacencyCustomizerTest extends WriterCustomizerTest { public void deleteCurrentAttributes() throws Exception { customizer.deleteCurrentAttributes(validId, validData, writeContext); verify(api, times(1)).lispAddDelAdjacency(requestCaptor.capture()); - verifyRequest(requestCaptor.getValue(), 0, new byte[]{-64, -88, 2, 1}, 32, new byte[]{-64, -88, 5, 2}, + verifyRequest(requestCaptor.getValue(), 0, new byte[]{-64, -88, 2, 1}, 32, new byte[]{-64, -88, 2, 3}, 32, IPV4.getValue(), 2); + verify(adjacenciesMappingContext, times(1)).removeForIndex("adj-one", mappingContext); } private static void verifyRequest(final LispAddDelAdjacency request, final int isAdd, final byte[] leid, diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/util/AdjacencyMappingContextTestHelper.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/util/AdjacencyMappingContextTestHelper.java new file mode 100644 index 000000000..1d6615472 --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/util/AdjacencyMappingContextTestHelper.java @@ -0,0 +1,126 @@ +/* + * 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.util; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.mockito.Mockito.doReturn; + +import com.google.common.base.Optional; +import com.google.common.collect.Lists; +import io.fd.honeycomb.translate.MappingContext; +import java.util.List; +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.MappingsBuilder; +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; + +/** + * Utility for mocking adjacency mappings + */ +public interface AdjacencyMappingContextTestHelper { + + /** + * Creates {@link Mapping} for given data. + * + * @param pair to be mapped + * @param id to be mapped + * @return eid to id mapping + */ + default Optional<Mapping> mapping(@Nonnull final EidIdentificatorPair pair, final String id) { + return Optional.of(new MappingBuilder().setEidIdentificatorPair(pair).setId(id).build()); + } + + /** + * Creates {@link KeyedInstanceIdentifier} for {@link Mapping} in {@link AdjacenciesIdentificationContexts}. + * + * @param id identificator of the mapping + * @param mappingContextName identificator of the mapping context + * @return identifier for the mapping + */ + static KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid(@Nonnull final String id, + @Nonnull final String mappingContextName) { + return InstanceIdentifier.create(AdjacenciesIdentificationContexts.class).child(AdjacenciesIdentification.class, + new AdjacenciesIdentificationKey(mappingContextName)).child(Mappings.class) + .child(Mapping.class, new MappingKey(id)); + } + + static EidIdentificatorPair pairOf(@Nonnull final String local, @Nonnull final String remote) { + return new EidIdentificatorPairBuilder() + .setLocalEidId(new MappingId(checkNotNull(local, "Local id cannot be null"))) + .setRemoteEidId(new MappingId(checkNotNull(remote, "Remote id cannot be null"))) + .build(); + } + + /** + * Stubs {@link MappingContext#read} to include given mapping in {@link AdjacenciesIdentification}. + * + * @param mappingContext mock instance of {@link MappingContext} + * @param localEidId local id for identification pair + * @param remoteEidId remote id for identification pair + * @param mappingName index to be mapped + * @param namingContextName name of the naming context + */ + default void defineAdjacencyMapping(@Nonnull final MappingContext mappingContext, @Nonnull final String localEidId, + @Nonnull final String remoteEidId, @Nonnull final String mappingName, + @Nonnull final String namingContextName) { + final KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid = mappingIid(mappingName, namingContextName); + final InstanceIdentifier<Mappings> mappingsIid = mappingIid.firstIdentifierOf(Mappings.class); + + final Optional<Mapping> singleMapping = mapping(pairOf(localEidId, remoteEidId), mappingName); + final List<Mapping> list = Common.getMappingList(mappingContext, mappingsIid); + list.add(singleMapping.get()); + + doReturn(Optional.of(new MappingsBuilder().setMapping(list).build())).when(mappingContext).read(mappingsIid); + doReturn(singleMapping).when(mappingContext).read(mappingIid); + } + + default void noAdjacencyMappingDefined(@Nonnull final MappingContext mappingContext, @Nonnull final String name, + @Nonnull final String namingContextName) { + final InstanceIdentifier<Mappings> iid = + mappingIid(name, namingContextName).firstIdentifierOf(Mappings.class); + final List<Mapping> list = Common.getMappingList(mappingContext, iid); + + doReturn(Optional.of(new MappingsBuilder().setMapping(list).build())).when(mappingContext).read(iid); + doReturn(Optional.absent()).when(mappingContext).read(mappingIid(name, namingContextName)); + } + + final class Common { + private static List<Mapping> getMappingList(@Nonnull final MappingContext mappingContext, + @Nonnull final InstanceIdentifier<Mappings> mappingsIid) { + final Optional<Mappings> previousMappings = mappingContext.read(mappingsIid); + final MappingsBuilder mappingsBuilder; + if (previousMappings != null && previousMappings.isPresent()) { + mappingsBuilder = new MappingsBuilder(previousMappings.get()); + } else { + mappingsBuilder = new MappingsBuilder(); + mappingsBuilder.setMapping(Lists.newArrayList()); + } + return mappingsBuilder.getMapping(); + } + } + +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/util/EidMappingContextHelper.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/util/EidMappingContextHelper.java index 296252915..70d536135 100644 --- a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/util/EidMappingContextHelper.java +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/util/EidMappingContextHelper.java @@ -76,8 +76,8 @@ public interface EidMappingContextHelper { * @param mappingName index to be mapped * @param namingContextName name of the naming context */ - default void defineMapping(@Nonnull final MappingContext mappingContext, @Nonnull final Eid eid, - final MappingId mappingName, @Nonnull final String namingContextName) { + default void defineEidMapping(@Nonnull final MappingContext mappingContext, @Nonnull final Eid eid, + final MappingId mappingName, @Nonnull final String namingContextName) { final KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid = mappingIid(mappingName, namingContextName); final InstanceIdentifier<Mappings> mappingsIid = mappingIid.firstIdentifierOf(Mappings.class); @@ -89,6 +89,16 @@ public interface EidMappingContextHelper { doReturn(singleMapping).when(mappingContext).read(mappingIid); } + default void noEidMappingDefined(@Nonnull final MappingContext mappingContext, @Nonnull final String name, + @Nonnull final String namingContextName) { + final InstanceIdentifier<Mappings> iid = + mappingIid(new MappingId(name), namingContextName).firstIdentifierOf(Mappings.class); + final List<Mapping> list = Common.getMappingList(mappingContext, iid); + + doReturn(Optional.of(new MappingsBuilder().setMapping(list).build())).when(mappingContext).read(iid); + doReturn(Optional.absent()).when(mappingContext).read(mappingIid(new MappingId(name), namingContextName)); + } + final class Common { private static List<Mapping> getMappingList(@Nonnull final MappingContext mappingContext, @Nonnull final InstanceIdentifier<Mappings> mappingsIid) { diff --git a/lisp/lisp2vpp/src/test/resources/adjacencies-identification-context.json b/lisp/lisp2vpp/src/test/resources/adjacencies-identification-context.json new file mode 100644 index 000000000..795b548a4 --- /dev/null +++ b/lisp/lisp2vpp/src/test/resources/adjacencies-identification-context.json @@ -0,0 +1,29 @@ + +{ + + "mappings": { + "mapping": [ + { + "id": "first", + "eid-identificator-pair": { + "local-eid-id": "local-eid-1", + "remote-eid-id": "remote-eid-1" + } + }, + { + "id": "second", + "eid-identificator-pair": { + "local-eid-id": "local-eid-2", + "remote-eid-id": "remote-eid-2" + } + }, + { + "id": "third", + "eid-identificator-pair": { + "local-eid-id": "local-eid-3", + "remote-eid-id": "remote-eid-3" + } + } + ] + } +}
\ No newline at end of file |