From 03c9a24ebf7bee3ae767236b1fd3ae0ce8fccec6 Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Thu, 3 Nov 2016 09:37:28 +0100 Subject: HONEYCOMB-259 - CacheKeyFactory Provides logic for creating scoped keys Change-Id: I126bcb9255b4f8a3f2585f50e6e718948581e7f0 Signed-off-by: Jan Srnicek --- .../translate/util/read/cache/CacheKeyFactory.java | 31 +++++ .../util/read/cache/DumpCacheManager.java | 34 +++-- .../util/read/cache/IdentifierCacheKeyFactory.java | 122 +++++++++++++++++ .../read/cache/IdentifierCacheKeyFactoryTest.java | 144 +++++++++++++++++++++ .../read/BridgeDomainSubtableCustomizer.java | 13 +- .../lisp/translate/read/InterfaceCustomizer.java | 6 +- .../read/ItrRemoteLocatorSetCustomizer.java | 4 +- .../translate/read/LocalMappingCustomizer.java | 10 +- .../lisp/translate/read/LocatorSetCustomizer.java | 5 +- .../lisp/translate/read/MapResolverCustomizer.java | 15 ++- .../translate/read/RemoteMappingCustomizer.java | 45 +++++-- .../lisp/translate/read/VniTableCustomizer.java | 5 +- .../lisp/translate/read/VrfSubtableCustomizer.java | 4 +- .../read/factory/EidTableReaderFactory.java | 4 +- .../lisp/translate/read/trait/SubtableReader.java | 10 +- .../lisp/translate/write/LocatorSetCustomizer.java | 4 - .../read/RemoteMappingCustomizerTest.java | 5 +- .../nat/read/ExternalIpPoolCustomizer.java | 7 +- .../honeycomb/nat/read/MappingEntryCustomizer.java | 9 +- .../honeycomb/nat/read/NatInstanceCustomizer.java | 7 +- .../io/fd/honeycomb/nat/read/NatReaderFactory.java | 19 ++- .../interfacesstate/ip/Ipv4AddressCustomizer.java | 23 ++-- .../ip/SubInterfaceIpv4AddressCustomizer.java | 5 +- .../ip/Ipv4AddressCustomizerTest.java | 15 ++- .../vpp/util/cache/DumpCacheManagerTest.java | 36 ++++-- 25 files changed, 459 insertions(+), 123 deletions(-) create mode 100644 infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/CacheKeyFactory.java create mode 100644 infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/IdentifierCacheKeyFactory.java create mode 100644 infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/cache/IdentifierCacheKeyFactoryTest.java diff --git a/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/CacheKeyFactory.java b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/CacheKeyFactory.java new file mode 100644 index 000000000..1b444ba3c --- /dev/null +++ b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/CacheKeyFactory.java @@ -0,0 +1,31 @@ +/* + * 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.translate.util.read.cache; + +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Provides keys for provided {@code InstanceIdentifier} + */ +public interface CacheKeyFactory { + + /** + * Construct key accordingly to provided {@code InstanceIdentifier} + */ + String createKey(@Nonnull final InstanceIdentifier actualContextIdentifier); +} diff --git a/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/DumpCacheManager.java b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/DumpCacheManager.java index f5895038e..f1b265dec 100644 --- a/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/DumpCacheManager.java +++ b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/DumpCacheManager.java @@ -30,6 +30,9 @@ import org.slf4j.LoggerFactory; /** * Manager responsible for returning Data object dumps
either from cache or by invoking specified {@link * EntityDumpExecutor} + * + * @param Type of data returned by {@code EntityDumpExecutor},and stored cache + * @param Type of dumping params */ public final class DumpCacheManager { @@ -37,27 +40,29 @@ public final class DumpCacheManager { private final EntityDumpExecutor dumpExecutor; private final EntityDumpPostProcessingFunction postProcessor; + private final CacheKeyFactory cacheKeyFactory; private DumpCacheManager(DumpCacheManagerBuilder builder) { this.dumpExecutor = builder.dumpExecutor; this.postProcessor = builder.postProcessingFunction; + this.cacheKeyFactory = builder.cacheKeyFactory; } /** * Returns {@link Optional} of dump * * @param identifier identifier for origin of dumping context - * @param entityKey key that defines scope for caching * @param cache modification cache of current transaction * @param dumpParams parameters to configure dump request * @throws ReadFailedException if execution of dumping request failed - * @returns If present in cache ,returns cached instance, if not, tries to dump data using provided executor, otherwise - * Optional.absent() + * @returns If present in cache ,returns cached instance, if not, tries to dump data using provided executor, + * otherwise Optional.absent() */ - public Optional getDump(@Nonnull final InstanceIdentifier identifier, @Nonnull String entityKey, - @Nonnull ModificationCache cache, final U dumpParams) + public Optional getDump(@Nonnull final InstanceIdentifier identifier, + @Nonnull final ModificationCache cache, final U dumpParams) throws ReadFailedException { + final String entityKey = this.cacheKeyFactory.createKey(identifier); // this key binding to every log has its logic ,because every customizer have its own cache manager and if // there is need for debugging/fixing some complex call with a lot of data,you can get lost in those logs LOG.debug("Loading dump for KEY[{}]", entityKey); @@ -81,29 +86,42 @@ public final class DumpCacheManager { public static final class DumpCacheManagerBuilder { + private static final CacheKeyFactory DEFAULT_CACHE_KEY_FACTORY_INSTANCE = new IdentifierCacheKeyFactory(); + private EntityDumpExecutor dumpExecutor; private EntityDumpPostProcessingFunction postProcessingFunction; + private CacheKeyFactory cacheKeyFactory; public DumpCacheManagerBuilder() { // for cases when user does not set specific post-processor postProcessingFunction = new NoopDumpPostProcessingFunction(); + + //use no additional scopes version by default + cacheKeyFactory = DEFAULT_CACHE_KEY_FACTORY_INSTANCE; } - public DumpCacheManagerBuilder withExecutor(@Nonnull EntityDumpExecutor executor) { + public DumpCacheManagerBuilder withExecutor(@Nonnull final EntityDumpExecutor executor) { this.dumpExecutor = executor; return this; } public DumpCacheManagerBuilder withPostProcessingFunction( - EntityDumpPostProcessingFunction postProcessingFunction) { + @Nonnull final EntityDumpPostProcessingFunction postProcessingFunction) { this.postProcessingFunction = postProcessingFunction; return this; } + public DumpCacheManagerBuilder withCacheKeyFactory(@Nonnull final CacheKeyFactory cacheKeyFactory) { + this.cacheKeyFactory = cacheKeyFactory; + return this; + } + public DumpCacheManager build() { checkNotNull(dumpExecutor, "Dump executor cannot be null"); checkNotNull(postProcessingFunction, - "Dump post-processor cannot be null cannot be null, default implementation is used if its not set"); + "Dump post-processor cannot be null cannot be null, default implementation is used when not set explicitly"); + checkNotNull(cacheKeyFactory, + "Cache key factory cannot be null, default non-extended implementation is used when not set explicitly"); return new DumpCacheManager<>(this); } diff --git a/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/IdentifierCacheKeyFactory.java b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/IdentifierCacheKeyFactory.java new file mode 100644 index 000000000..51f47e137 --- /dev/null +++ b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/cache/IdentifierCacheKeyFactory.java @@ -0,0 +1,122 @@ +/* + * 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.translate.util.read.cache; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem; + +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Factory providing cache keys to easier switching between scopes of caching + */ +public final class IdentifierCacheKeyFactory implements CacheKeyFactory { + + private static final String KEY_PARTS_SEPARATOR = "|"; + + // should be Set>>, but that's not possible for wildcards + private final Set> additionalKeyTypes; + + /** + * Construct simple cache key factory + */ + public IdentifierCacheKeyFactory() { + this(Collections.emptySet()); + } + + /** + * @param additionalKeyTypes Additional types from path of cached type, that are specifying scope + */ + public IdentifierCacheKeyFactory(@Nonnull final Set> additionalKeyTypes) { + // verify that all are non-null and identifiable + this.additionalKeyTypes = checkNotNull(additionalKeyTypes, "Additional key types can't be null").stream() + .map(IdentifierCacheKeyFactory::verifyNotNull) + .map(IdentifierCacheKeyFactory::verifyIsIdentifiable) + .collect(Collectors.toSet()); + } + + @Override + public String createKey(@Nonnull final InstanceIdentifier actualContextIdentifier) { + + checkNotNull(actualContextIdentifier, "Cannot construct key for null InstanceIdentifier"); + + // easiest case when only simple key is needed + if (additionalKeyTypes.isEmpty()) { + return actualContextIdentifier.getTargetType().toString(); + } + + checkArgument(isUniqueKeyConstructable(actualContextIdentifier), + "Unable to construct unique key, required key types : %s, provided paths : %s", additionalKeyTypes, + actualContextIdentifier.getPathArguments()); + + return String + .join(KEY_PARTS_SEPARATOR, additionalKeys(actualContextIdentifier), + actualContextIdentifier.getTargetType().toString()); + } + + /** + * Verifies that all requested key parts have keys + */ + private boolean isUniqueKeyConstructable(final InstanceIdentifier actualContextIdentifier) { + return StreamSupport.stream(actualContextIdentifier.getPathArguments().spliterator(), false) + .filter(this::isAdditionalScope) + .filter(this::isIdentifiable) + .count() == additionalKeyTypes.size(); + } + + private boolean isAdditionalScope(final InstanceIdentifier.PathArgument pathArgument) { + return additionalKeyTypes.contains(pathArgument.getType()); + } + + private boolean isIdentifiable(final InstanceIdentifier.PathArgument pathArgument) { + return pathArgument instanceof IdentifiableItem; + } + + + private String additionalKeys(final InstanceIdentifier actualContextIdentifier) { + return StreamSupport.stream(actualContextIdentifier.getPathArguments().spliterator(), false) + .filter(this::isAdditionalScope) + .filter(this::isIdentifiable) + .map(IdentifiableItem.class::cast) + .map(IdentifierCacheKeyFactory::bindKeyString) + .collect(Collectors.joining(KEY_PARTS_SEPARATOR)); + } + + private static String bindKeyString(IdentifiableItem identifiableItem) { + return String.format("%s[%s]", identifiableItem.getType().getTypeName(), identifiableItem.getKey()); + } + + private static Class verifyNotNull(final Class type) { + return checkNotNull(type, "Cannot use null as key"); + } + + /** + * Initial check if provided scope variables are identifiable aka. can be used to create unique cache key + */ + private static Class verifyIsIdentifiable(final Class type) { + checkArgument(Identifiable.class.isAssignableFrom(type), "Type %s is not Identifiable", type); + return type; + } +} diff --git a/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/cache/IdentifierCacheKeyFactoryTest.java b/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/cache/IdentifierCacheKeyFactoryTest.java new file mode 100644 index 000000000..e7eae552c --- /dev/null +++ b/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/cache/IdentifierCacheKeyFactoryTest.java @@ -0,0 +1,144 @@ +/* + * 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.translate.util.read.cache; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableSet; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class IdentifierCacheKeyFactoryTest { + + private interface SuperDataObject extends DataObject { + } + + private interface DataObjectParent extends DataObject, ChildOf, Identifiable { + } + + private class DataObjectParentKey implements Identifier { + } + + private interface DataObjectChild extends DataObject, ChildOf, Identifiable { + } + + private class DataObjectChildKey implements Identifier { + } + + private DataObjectParentKey parentKey; + private DataObjectChildKey childKey; + private InstanceIdentifier identifierBothKeyed; + private InstanceIdentifier identifierOneMissing; + private InstanceIdentifier identifierNoneKeyed; + + private IdentifierCacheKeyFactory simpleKeyFactory; + private IdentifierCacheKeyFactory complexKeyFactory; + + @Before + public void init() { + parentKey = new DataObjectParentKey(); + childKey = new DataObjectChildKey(); + identifierBothKeyed = InstanceIdentifier.create(SuperDataObject.class).child(DataObjectParent.class, parentKey) + .child(DataObjectChild.class, childKey); + identifierOneMissing = InstanceIdentifier.create(DataObjectChild.class); + identifierNoneKeyed = InstanceIdentifier.create(SuperDataObject.class).child(DataObjectParent.class) + .child(DataObjectChild.class); + + complexKeyFactory = new IdentifierCacheKeyFactory(ImmutableSet.of(DataObjectParent.class)); + simpleKeyFactory = new IdentifierCacheKeyFactory(); + } + + @Test + public void createKeyBothKeyedComplex() { + final String key = complexKeyFactory.createKey(identifierBothKeyed); + + /** + * Should pass because key constructed in this case should look like : + * additional_scope_type[additional_scope_type_key]|cached_type + * */ + verifyComplexKey(key); + } + + /** + * Should fail because provided identifier does'nt contain all requested key parts + */ + @Test(expected = IllegalArgumentException.class) + public void createKeyOneMissingComplex() { + complexKeyFactory.createKey(identifierOneMissing); + } + + /** + * Should fail because request paths are not keyed + */ + @Test(expected = IllegalArgumentException.class) + public void createKeyNoneKeyedComplex() { + complexKeyFactory.createKey(identifierNoneKeyed); + } + + @Test + public void createKeyBothKeyedSimple() { + final String key = simpleKeyFactory.createKey(identifierBothKeyed); + + /** + * Should pass because key constructed in this case should look like : cached_type + * */ + verifySimpleKey(key); + } + + @Test + public void createKeyOneMissingSimple() { + final String key = simpleKeyFactory.createKey(identifierOneMissing); + /** + * Should pass because key constructed in this case should look like : cached_type + * */ + verifySimpleKey(key); + } + + /** + * Should fail because request paths are not keyed + */ + @Test + public void createKeyNoneKeyedSimple() { + final String key = simpleKeyFactory.createKey(identifierNoneKeyed); + /** + * Should pass because key constructed in this case should look like : cached_type + * */ + verifySimpleKey(key); + } + + private void verifyComplexKey(final String key) { + assertTrue(key.contains(DataObjectParent.class.getTypeName())); + assertTrue(key.contains(parentKey.toString())); + assertTrue(key.contains(DataObjectChild.class.getTypeName())); + assertFalse(key.contains(childKey.toString())); + assertFalse(key.contains(SuperDataObject.class.getTypeName())); + } + + private void verifySimpleKey(final String key) { + assertFalse(key.contains(DataObjectParent.class.getTypeName())); + assertFalse(key.contains(parentKey.toString())); + assertTrue(key.contains(DataObjectChild.class.getTypeName())); + assertFalse(key.contains(childKey.toString())); + assertFalse(key.contains(SuperDataObject.class.getTypeName())); + } +} \ No newline at end of file diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/BridgeDomainSubtableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/BridgeDomainSubtableCustomizer.java index 3c6ace8e7..1d0d8a019 100644 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/BridgeDomainSubtableCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/BridgeDomainSubtableCustomizer.java @@ -48,17 +48,18 @@ public class BridgeDomainSubtableCustomizer extends FutureJVppCustomizer impleme ReaderCustomizer, SubtableReader { private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainSubtableCustomizer.class); - private static final String CACHE_KEY = BridgeDomainSubtableCustomizer.class.getName(); - private final DumpCacheManager dumpManager; + private final DumpCacheManager + dumpManager; private final NamingContext bridgeDomainContext; public BridgeDomainSubtableCustomizer(@Nonnull final FutureJVppCore futureJvppCore, @Nonnull final NamingContext bridgeDomainContext) { super(futureJvppCore); - dumpManager = new DumpCacheManagerBuilder() - .withExecutor(createExecutor(futureJvppCore)) - .build(); + dumpManager = + new DumpCacheManagerBuilder() + .withExecutor(createExecutor(futureJvppCore)) + .build(); this.bridgeDomainContext = checkNotNull(bridgeDomainContext, "Bridge domain context cannot be null"); } @@ -77,7 +78,7 @@ public class BridgeDomainSubtableCustomizer extends FutureJVppCustomizer impleme LOG.debug("Read attributes for id {}", id); //dumps only L2(bridge domains) final Optional reply = - readSubtable(dumpManager, CACHE_KEY, ctx.getModificationCache(), id, L2_PARAMS); + dumpManager.getDump(id, ctx.getModificationCache(), L2_PARAMS); if (!reply.isPresent() || reply.get().lispEidTableMapDetails.isEmpty()) { return; diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/InterfaceCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/InterfaceCustomizer.java index 0e1c34483..7291afb03 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/InterfaceCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/InterfaceCustomizer.java @@ -55,8 +55,6 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListReaderCustomizer, LocatorReader { - private static final String KEY_BASE = InterfaceCustomizer.class.getName(); - private final NamingContext interfaceContext; private final NamingContext locatorSetContext; private final DumpCacheManager dumpCacheManager; @@ -97,7 +95,7 @@ public class InterfaceCustomizer new LocatorDumpParamsBuilder().setLocatorSetIndex(locatorSetIndexIndex).build(); final Optional reply = - dumpCacheManager.getDump(id, KEY_BASE, ctx.getModificationCache(), params); + dumpCacheManager.getDump(id, ctx.getModificationCache(), params); if (!reply.isPresent() || reply.get().lispLocatorDetails.isEmpty()) { return; @@ -129,7 +127,7 @@ public class InterfaceCustomizer .setLocatorSetIndex(locatorSetContext.getIndex(name, context.getMappingContext())).build(); final Optional reply = - dumpCacheManager.getDump(id, KEY_BASE, context.getModificationCache(), params); + dumpCacheManager.getDump(id, context.getModificationCache(), params); if (!reply.isPresent() || reply.get().lispLocatorDetails.isEmpty()) { return Collections.emptyList(); diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/ItrRemoteLocatorSetCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/ItrRemoteLocatorSetCustomizer.java index c9be45cf7..8e8fd5848 100644 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/ItrRemoteLocatorSetCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/ItrRemoteLocatorSetCustomizer.java @@ -43,8 +43,6 @@ public class ItrRemoteLocatorSetCustomizer extends FutureJVppCustomizer implements ReaderCustomizer, ByteDataTranslator, JvppReplyConsumer { - private static final String CACHE_KEY = ItrRemoteLocatorSetCustomizer.class.getName(); - private final DumpCacheManager dumpCacheManager; public ItrRemoteLocatorSetCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { @@ -68,7 +66,7 @@ public class ItrRemoteLocatorSetCustomizer extends FutureJVppCustomizer throws ReadFailedException { final Optional reply = - dumpCacheManager.getDump(id, CACHE_KEY, ctx.getModificationCache(), NO_PARAMS); + dumpCacheManager.getDump(id, ctx.getModificationCache(), NO_PARAMS); if (!reply.isPresent() || reply.get().locatorSetName == null) { return; } diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocalMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocalMappingCustomizer.java index 74fbf6f20..e989a393d 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocalMappingCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocalMappingCustomizer.java @@ -65,7 +65,6 @@ public class LocalMappingCustomizer MappingReader { private static final Logger LOG = LoggerFactory.getLogger(LocalMappingCustomizer.class); - private static final String KEY = LocalMappingCustomizer.class.getName(); private final DumpCacheManager dumpManager; private final NamingContext locatorSetContext; @@ -113,7 +112,7 @@ public class LocalMappingCustomizer LOG.debug("Dumping data for LocalMappings(id={})", id); final Optional replyOptional = - dumpManager.getDump(id, bindKey("SPECIFIC_" + localMappingId), ctx.getModificationCache(), dumpParams); + dumpManager.getDump(id, ctx.getModificationCache(), dumpParams); if (!replyOptional.isPresent() || replyOptional.get().lispEidTableDetails.isEmpty()) { return; @@ -158,7 +157,7 @@ public class LocalMappingCustomizer LOG.debug("Dumping data for LocalMappings(id={})", id); final Optional replyOptional = - dumpManager.getDump(id, bindKey("ALL_LOCAL"), context.getModificationCache(), dumpParams); + dumpManager.getDump(id, context.getModificationCache(), dumpParams); if (!replyOptional.isPresent() || replyOptional.get().lispEidTableDetails.isEmpty()) { return Collections.emptyList(); @@ -179,9 +178,4 @@ public class LocalMappingCustomizer public void merge(Builder builder, List readData) { ((LocalMappingsBuilder) builder).setLocalMapping(readData); } - - private static String bindKey(String prefix) { - return prefix + "_" + KEY; - } - } diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocatorSetCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocatorSetCustomizer.java index 9a55e5006..ff0855a74 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocatorSetCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocatorSetCustomizer.java @@ -49,7 +49,6 @@ public class LocatorSetCustomizer extends FutureJVppCustomizer implements ListReaderCustomizer, ByteDataTranslator, LocatorSetReader { - private static final String LOCATOR_SETS_CACHE_ID = LocatorSetCustomizer.class.getName(); private static final Logger LOG = LoggerFactory.getLogger(LocatorSetCustomizer.class); private final DumpCacheManager dumpManager; @@ -75,7 +74,7 @@ public class LocatorSetCustomizer extends FutureJVppCustomizer LOG.debug("Reading attributes for Locator Set {}", id); final Optional dumpOptional = - dumpManager.getDump(id, LOCATOR_SETS_CACHE_ID, ctx.getModificationCache(), NO_PARAMS); + dumpManager.getDump(id, ctx.getModificationCache(), NO_PARAMS); if (!dumpOptional.isPresent() || dumpOptional.get().lispLocatorSetDetails.isEmpty()) { return; @@ -104,7 +103,7 @@ public class LocatorSetCustomizer extends FutureJVppCustomizer LOG.debug("Dumping Locator Set {}", id); final Optional dumpOptional = - dumpManager.getDump(id, LOCATOR_SETS_CACHE_ID, context.getModificationCache(), NO_PARAMS); + dumpManager.getDump(id, context.getModificationCache(), NO_PARAMS); if (!dumpOptional.isPresent() || dumpOptional.get().lispLocatorSetDetails.isEmpty()) { return Collections.emptyList(); diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/MapResolverCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/MapResolverCustomizer.java index 5c453d5ff..fb44e13e9 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/MapResolverCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/MapResolverCustomizer.java @@ -51,16 +51,17 @@ public class MapResolverCustomizer extends FutureJVppCustomizer JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(MapResolverCustomizer.class); - private static final String MAP_RESOLVERS_CACHE_ID = MapResolverCustomizer.class.getName(); private final DumpCacheManager dumpManager; public MapResolverCustomizer(FutureJVppCore futureJvpp) { super(futureJvpp); - this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor((identifier, params) -> getReplyForRead( - futureJvpp.lispMapResolverDump(new LispMapResolverDump()).toCompletableFuture(), identifier)) - .build(); + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor((identifier, params) -> getReplyForRead( + futureJvpp.lispMapResolverDump(new LispMapResolverDump()).toCompletableFuture(), + identifier)) + .build(); } @Override @@ -74,7 +75,7 @@ public class MapResolverCustomizer extends FutureJVppCustomizer LOG.debug("Reading attributes..."); final Optional dumpOptional = - dumpManager.getDump(id, MAP_RESOLVERS_CACHE_ID, ctx.getModificationCache(), NO_PARAMS); + dumpManager.getDump(id, ctx.getModificationCache(), NO_PARAMS); if (!dumpOptional.isPresent() || dumpOptional.get().lispMapResolverDetails.isEmpty()) { LOG.warn("No data dumped"); @@ -105,7 +106,7 @@ public class MapResolverCustomizer extends FutureJVppCustomizer LOG.debug("Dumping MapResolver..."); final Optional dumpOptional = - dumpManager.getDump(id, MAP_RESOLVERS_CACHE_ID, context.getModificationCache(), NO_PARAMS); + dumpManager.getDump(id, context.getModificationCache(), NO_PARAMS); if (!dumpOptional.isPresent() || dumpOptional.get().lispMapResolverDetails.isEmpty()) { return Collections.emptyList(); diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizer.java index 18bafe179..b0e9056fc 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizer.java @@ -24,6 +24,7 @@ import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsD import static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MapReplyAction.NoAction; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; import io.fd.honeycomb.lisp.context.util.EidMappingContext; import io.fd.honeycomb.lisp.translate.read.dump.executor.params.LocatorDumpParams; import io.fd.honeycomb.lisp.translate.read.dump.executor.params.LocatorDumpParams.LocatorDumpParamsBuilder; @@ -32,15 +33,18 @@ import io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpPara import io.fd.honeycomb.lisp.translate.read.trait.LocatorReader; import io.fd.honeycomb.lisp.translate.read.trait.MappingReader; import io.fd.honeycomb.lisp.translate.util.EidTranslator; +import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.ModificationCache; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; import io.fd.honeycomb.translate.vpp.util.AddressTranslator; import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator; import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.vpp.util.NamingContext; import io.fd.vpp.jvpp.core.dto.LispEidTableDetails; import io.fd.vpp.jvpp.core.dto.LispEidTableDetailsReplyDump; import io.fd.vpp.jvpp.core.dto.LispLocatorDetails; @@ -67,6 +71,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.LocatorBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.LocatorKey; 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.locator.sets.grouping.LocatorSets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSetKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.locator.set.Interface; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -81,23 +89,29 @@ public class RemoteMappingCustomizer extends FutureJVppCustomizer EidTranslator, AddressTranslator, ByteDataTranslator, MappingReader, LocatorReader { private static final Logger LOG = LoggerFactory.getLogger(RemoteMappingCustomizer.class); - private static final String KEY = RemoteMappingCustomizer.class.getName(); private final DumpCacheManager dumpManager; private final DumpCacheManager locatorsDumpManager; + private final NamingContext locatorSetContext; private final EidMappingContext remoteMappingContext; - public RemoteMappingCustomizer(@Nonnull FutureJVppCore futureJvpp, - @Nonnull EidMappingContext remoteMappingContext) { + public RemoteMappingCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final NamingContext locatorSetContext, + @Nonnull final EidMappingContext remoteMappingContext) { super(futureJvpp); + this.locatorSetContext = checkNotNull(locatorSetContext, "Locator sets context not present"); this.remoteMappingContext = checkNotNull(remoteMappingContext, "Remote mappings not present"); + // this one should have default scope == RemoteMapping this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder() .withExecutor(createMappingDumpExecutor(futureJvpp)) .build(); + + // cache key needs to have locator set scope to not mix with cached data this.locatorsDumpManager = new DumpCacheManager.DumpCacheManagerBuilder() .withExecutor(createLocatorDumpExecutor(futureJvpp)) + .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(LocatorSet.class))) .build(); } @@ -138,7 +152,7 @@ public class RemoteMappingCustomizer extends FutureJVppCustomizer LOG.debug("Dumping data for LocalMappings(id={})", id); final Optional replyOptional = - dumpManager.getDump(id, bindKey("SPECIFIC_" + remoteMappingId), ctx.getModificationCache(), dumpParams); + dumpManager.getDump(id, ctx.getModificationCache(), dumpParams); if (!replyOptional.isPresent() || replyOptional.get().lispEidTableDetails.isEmpty()) { return; @@ -158,7 +172,7 @@ public class RemoteMappingCustomizer extends FutureJVppCustomizer builder.setTtl(resolveTtl(details.ttl)); builder.setAuthoritative( new RemoteMapping.Authoritative(byteToBoolean(details.authoritative))); - resolverMappings(id, builder, details, ctx.getModificationCache()); + resolveMappings(id, builder, details, ctx.getModificationCache(), ctx.getMappingContext()); } //compensate ~0 as default value of ttl @@ -190,7 +204,7 @@ public class RemoteMappingCustomizer extends FutureJVppCustomizer LOG.debug("Dumping data for LocalMappings(id={})", id); final Optional replyOptional = - dumpManager.getDump(id, bindKey("ALL_REMOTE"), context.getModificationCache(), dumpParams); + dumpManager.getDump(id, context.getModificationCache(), dumpParams); if (!replyOptional.isPresent() || replyOptional.get().lispEidTableDetails.isEmpty()) { return Collections.emptyList(); @@ -213,13 +227,10 @@ public class RemoteMappingCustomizer extends FutureJVppCustomizer ((RemoteMappingsBuilder) builder).setRemoteMapping(readData); } - private String bindKey(String prefix) { - return prefix + "_" + KEY; - } - - private void resolverMappings(final InstanceIdentifier id, final RemoteMappingBuilder builder, - final LispEidTableDetails details, - final ModificationCache cache) throws ReadFailedException { + private void resolveMappings(final InstanceIdentifier id, final RemoteMappingBuilder builder, + final LispEidTableDetails details, + final ModificationCache cache, + final MappingContext mappingContext) throws ReadFailedException { if (details.action != 0) { // in this case ,negative action was defined @@ -230,8 +241,14 @@ public class RemoteMappingCustomizer extends FutureJVppCustomizer // cache key needs to have locator set scope to not mix with cached data final Optional reply; + + // this will serve to achieve that locators have locator set scope + final InstanceIdentifier locatorIfaceIdentifier = InstanceIdentifier.create(LocatorSets.class) + .child(LocatorSet.class, + new LocatorSetKey(locatorSetContext.getName(details.locatorSetIndex, mappingContext))) + .child(Interface.class); try { - reply = locatorsDumpManager.getDump(id, KEY + "_locator_set_" + details.locatorSetIndex, cache, + reply = locatorsDumpManager.getDump(locatorIfaceIdentifier, cache, new LocatorDumpParamsBuilder().setLocatorSetIndex(details.locatorSetIndex).build()); } catch (ReadFailedException e) { throw new ReadFailedException(id, diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VniTableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VniTableCustomizer.java index d6f629ee4..49047bcc9 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VniTableCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VniTableCustomizer.java @@ -53,7 +53,6 @@ public class VniTableCustomizer extends FutureJVppCustomizer private static final Logger LOG = LoggerFactory.getLogger(VniTableCustomizer.class); - private static final String LISP_TABLE_ID_DUMP = VniTableCustomizer.class.getName(); private final DumpCacheManager dumpManager; public VniTableCustomizer(@Nonnull final FutureJVppCore futureJvpp) { @@ -88,7 +87,7 @@ public class VniTableCustomizer extends FutureJVppCustomizer LOG.trace("Reading all IDS..."); final Optional optionalReply = - dumpManager.getDump(id, LISP_TABLE_ID_DUMP, context.getModificationCache(), NO_PARAMS); + dumpManager.getDump(id, context.getModificationCache(), NO_PARAMS); if (!optionalReply.isPresent() || optionalReply.get().lispEidTableVniDetails.isEmpty()) { return Collections.emptyList(); @@ -107,7 +106,7 @@ public class VniTableCustomizer extends FutureJVppCustomizer VniTableKey key = new VniTableKey(id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier()); final Optional optionalReply = - dumpManager.getDump(id, LISP_TABLE_ID_DUMP, ctx.getModificationCache(), NO_PARAMS); + dumpManager.getDump(id, ctx.getModificationCache(), NO_PARAMS); if (!optionalReply.isPresent() || optionalReply.get().lispEidTableVniDetails.isEmpty()) { return; diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VrfSubtableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VrfSubtableCustomizer.java index 72d25af43..af48a6500 100644 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VrfSubtableCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VrfSubtableCustomizer.java @@ -47,7 +47,6 @@ public class VrfSubtableCustomizer extends FutureJVppCustomizer implements ReaderCustomizer, SubtableReader { private static final Logger LOG = LoggerFactory.getLogger(VrfSubtableCustomizer.class); - private static final String CACHE_KEY = VrfSubtableCustomizer.class.getName(); private final DumpCacheManager dumpManager; @@ -72,8 +71,7 @@ public class VrfSubtableCustomizer extends FutureJVppCustomizer final int vni = checkNotNull(id.firstKeyOf(VniTable.class), "Cannot find parent VNI Table") .getVirtualNetworkIdentifier().intValue(); - final Optional reply = - readSubtable(dumpManager, CACHE_KEY, ctx.getModificationCache(), id, L3_PARAMS); + final Optional reply = dumpManager.getDump(id, ctx.getModificationCache(), L3_PARAMS); if (!reply.isPresent() || reply.get().lispEidTableMapDetails.isEmpty()) { return; 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 a5805473e..dad04bff5 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 @@ -149,14 +149,14 @@ final class EidTableReaderFactory extends AbstractLispReaderFactoryBase implemen remoteMappingSubtreeId.child(Rlocs.class).child(Locator.class), remoteMappingSubtreeId.child(MapReply.class)), new GenericListReader<>(vrfTableRemoteMappingsInstanceIdentifier.child(RemoteMapping.class), - new RemoteMappingCustomizer(vppApi, remoteMappingContext))); + new RemoteMappingCustomizer(vppApi, locatorSetContext, remoteMappingContext))); registry.subtreeAdd(ImmutableSet.of(remoteMappingSubtreeId .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid.class), remoteMappingSubtreeId.child(Rlocs.class), remoteMappingSubtreeId.child(Rlocs.class).child(Locator.class), remoteMappingSubtreeId.child(MapReply.class)), new GenericListReader<>(bridgeDomainRemoteMappingsInstanceIdentifier.child(RemoteMapping.class), - new RemoteMappingCustomizer(vppApi, remoteMappingContext))); + new RemoteMappingCustomizer(vppApi, locatorSetContext, remoteMappingContext))); registry.addStructuralReader(vrfTableAdjacenciesInstanceIdentifier, AdjacenciesBuilder.class); registry.addStructuralReader(bridgeDomainAdjacenciesInstanceIdentifier, AdjacenciesBuilder.class); diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/trait/SubtableReader.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/trait/SubtableReader.java index 431bf9229..a4a6e21ab 100644 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/trait/SubtableReader.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/trait/SubtableReader.java @@ -34,6 +34,7 @@ import io.fd.vpp.jvpp.core.dto.LispEidTableMapDump; import io.fd.vpp.jvpp.core.future.FutureJVppCore; import javax.annotation.Nonnull; 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.vni.table.VrfSubtable; import org.opendaylight.yangtools.yang.binding.ChildOf; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -45,15 +46,6 @@ public interface SubtableReader extends JvppReplyConsumer { SubtableDumpParams L2_PARAMS = new SubtableDumpParamsBuilder().setL2(L2).build(); SubtableDumpParams L3_PARAMS = new SubtableDumpParamsBuilder().setL2(L3).build(); - default Optional readSubtable( - @Nonnull final DumpCacheManager dumpManager, - @Nonnull final String cacheKey, - @Nonnull final ModificationCache cache, - @Nonnull final InstanceIdentifier> id, - @Nonnull final SubtableDumpParams params) throws ReadFailedException { - return dumpManager.getDump(id, cacheKey, cache, params); - } - default EntityDumpExecutor createExecutor( @Nonnull final FutureJVppCore vppApi) { return (identifier, params) -> { diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizer.java index 701141ebc..749255836 100755 --- a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizer.java +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizer.java @@ -49,15 +49,11 @@ public class LocatorSetCustomizer extends FutureJVppCustomizer LocatorSetReader { private final NamingContext locatorSetContext; - private final DumpCacheManager dumpManager; public LocatorSetCustomizer(@Nonnull final FutureJVppCore futureJvpp, @Nonnull final NamingContext locatorSetContext) { super(futureJvpp); this.locatorSetContext = checkNotNull(locatorSetContext, "Locator set context cannot be null"); - this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(createExecutor(futureJvpp)) - .build(); } @Override diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizerTest.java index cff2dad51..27c243e8b 100644 --- a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizerTest.java +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizerTest.java @@ -27,6 +27,7 @@ import io.fd.honeycomb.lisp.context.util.EidMappingContext; import io.fd.honeycomb.lisp.translate.util.EidTranslator; import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.honeycomb.translate.vpp.util.NamingContext; import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; import io.fd.vpp.jvpp.core.dto.LispEidTableDetails; import io.fd.vpp.jvpp.core.dto.LispEidTableDetailsReplyDump; @@ -83,6 +84,7 @@ public class RemoteMappingCustomizerTest .child(RemoteMappings.class) .child(RemoteMapping.class, new RemoteMappingKey(new MappingId("remote-mapping"))); mockMappings(); + defineMapping(mappingContext,"loc-set",1,"loc-set-context"); } @@ -163,6 +165,7 @@ public class RemoteMappingCustomizerTest when(eidMappingContext.containsEid(new MappingId("remote-mapping"), mappingContext)).thenReturn(true); when(eidMappingContext.getEid(new MappingId("remote-mapping"), mappingContext)) .thenReturn(new EidBuilder().setAddress(EID_ADDRESS).build()); + } @Test @@ -233,6 +236,6 @@ public class RemoteMappingCustomizerTest @Override protected ReaderCustomizer initCustomizer() { - return new RemoteMappingCustomizer(api, eidMappingContext); + return new RemoteMappingCustomizer(api, new NamingContext("loc-set", "loc-set-context"), eidMappingContext); } } \ No newline at end of file diff --git a/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/ExternalIpPoolCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/ExternalIpPoolCustomizer.java index 959bfbdc1..0650280f1 100644 --- a/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/ExternalIpPoolCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/ExternalIpPoolCustomizer.java @@ -73,10 +73,11 @@ final class ExternalIpPoolCustomizer implements final Long poolId = id.firstKeyOf(ExternalIpAddressPool.class).getPoolId(); final SnatAddressDetails details = - dumpMgr.getDump(id, getClass().getName(), ctx.getModificationCache(), null) + dumpMgr.getDump(id, ctx.getModificationCache(), null) .or(new SnatAddressDetailsReplyDump()).snatAddressDetails.get(Math.toIntExact(poolId)); - builder.setExternalIpPool(new Ipv4Prefix(arrayToIpv4AddressNoZoneReversed(details.ipAddress).getValue() + "/32")); + builder.setExternalIpPool( + new Ipv4Prefix(arrayToIpv4AddressNoZoneReversed(details.ipAddress).getValue() + "/32")); builder.setPoolId(poolId); LOG.trace("External IP pool: {}. Read as: {}", id, builder); @@ -100,7 +101,7 @@ final class ExternalIpPoolCustomizer implements // That's why the write and read is not symmetrical in terms of data structure, instead, // this customizer also returns every single address as a 32 prefix and assigns an artificial key to them - final long addressCount = dumpMgr.getDump(id, getClass().getName(), ctx.getModificationCache(), null) + final long addressCount = dumpMgr.getDump(id, ctx.getModificationCache(), null) .or(new SnatAddressDetailsReplyDump()).snatAddressDetails.stream() .count(); diff --git a/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/MappingEntryCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/MappingEntryCustomizer.java index c525cb9da..df0a8e886 100644 --- a/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/MappingEntryCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/MappingEntryCustomizer.java @@ -58,8 +58,9 @@ final class MappingEntryCustomizer implements Ipv4Translator, private final DumpCacheManager dumpCacheManager; private final MappingEntryContext mappingEntryContext; - MappingEntryCustomizer(final DumpCacheManager dumpCacheManager, - final MappingEntryContext mappingEntryContext) { + MappingEntryCustomizer( + final DumpCacheManager dumpCacheManager, + final MappingEntryContext mappingEntryContext) { this.dumpCacheManager = dumpCacheManager; this.mappingEntryContext = mappingEntryContext; } @@ -79,7 +80,7 @@ final class MappingEntryCustomizer implements Ipv4Translator, final int idx = id.firstKeyOf(MappingEntry.class).getIndex().intValue(); final int natInstanceId = id.firstKeyOf(NatInstance.class).getId().intValue(); final List details = - dumpCacheManager.getDump(id, getClass().getName(), ctx.getModificationCache(), null) + dumpCacheManager.getDump(id, ctx.getModificationCache(), null) .or(new SnatStaticMappingDetailsReplyDump()).snatStaticMappingDetails; final SnatStaticMappingDetails snatStaticMappingDetails = mappingEntryContext.findDetails(details, natInstanceId, idx, ctx.getMappingContext()); @@ -116,7 +117,7 @@ final class MappingEntryCustomizer implements Ipv4Translator, LOG.trace("Listing IDs for all mapping-entries within nat-instance(vrf):{}", natInstanceId); final List entryKeys = - dumpCacheManager.getDump(id, getClass().getName(), context.getModificationCache(), null) + dumpCacheManager.getDump(id, context.getModificationCache(), null) .or(new SnatStaticMappingDetailsReplyDump()).snatStaticMappingDetails.stream() .filter(detail -> natInstanceId == detail.vrfId) .map(detail -> mappingEntryContext diff --git a/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/NatInstanceCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/NatInstanceCustomizer.java index 0c089e454..56965f7b4 100644 --- a/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/NatInstanceCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/NatInstanceCustomizer.java @@ -46,7 +46,8 @@ final class NatInstanceCustomizer implements InitializingListReaderCustomizer dumpCacheManager; - NatInstanceCustomizer(final DumpCacheManager dumpCacheManager) { + NatInstanceCustomizer( + final DumpCacheManager dumpCacheManager) { this.dumpCacheManager = dumpCacheManager; } @@ -72,10 +73,10 @@ final class NatInstanceCustomizer implements InitializingListReaderCustomizer vrfIds = - dumpCacheManager.getDump(id, getClass().getName(), context.getModificationCache(), null) + dumpCacheManager.getDump(id, context.getModificationCache(), null) .or(new SnatStaticMappingDetailsReplyDump()).snatStaticMappingDetails.stream() .map(detail -> detail.vrfId) - .map(vrfId -> new NatInstanceKey((long)vrfId)) + .map(vrfId -> new NatInstanceKey((long) vrfId)) .collect(Collectors.toList()); // Add default vrf id if not present diff --git a/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/NatReaderFactory.java b/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/NatReaderFactory.java index a44d1117e..ff0d1880c 100644 --- a/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/NatReaderFactory.java +++ b/nat/nat2vpp/src/main/java/io/fd/honeycomb/nat/read/NatReaderFactory.java @@ -47,7 +47,8 @@ public class NatReaderFactory implements ReaderFactory { private static final InstanceIdentifier NAT_OPER_ID = InstanceIdentifier.create(NatState.class); private static final InstanceIdentifier NAT_INSTANCES_ID = NAT_OPER_ID.child(NatInstances.class); private static final InstanceIdentifier NAT_INSTANCE_ID = NAT_INSTANCES_ID.child(NatInstance.class); - private static final InstanceIdentifier CURRENT_CONFIG = NAT_INSTANCE_ID.child(NatCurrentConfig.class); + private static final InstanceIdentifier CURRENT_CONFIG = + NAT_INSTANCE_ID.child(NatCurrentConfig.class); private static final InstanceIdentifier MAP_TABLE_ID = NAT_INSTANCE_ID.child(MappingTable.class); private static final InstanceIdentifier MAP_ENTRY_ID = MAP_TABLE_ID.child(MappingEntry.class); @@ -55,16 +56,20 @@ public class NatReaderFactory implements ReaderFactory { private final DumpCacheManager mapEntryDumpMgr; private final DumpCacheManager addressRangeDumpMgr; + @Inject public NatReaderFactory(final FutureJVppSnatFacade jvppSnat, final MappingEntryContext mappingEntryContext) { this.mappingEntryContext = mappingEntryContext; - this.mapEntryDumpMgr = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(new MappingEntryCustomizer.MappingEntryDumpExecutor(jvppSnat)) - .build(); - this.addressRangeDumpMgr = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(new ExternalIpPoolCustomizer.AddressRangeDumpExecutor(jvppSnat)) - .build(); + this.mapEntryDumpMgr = + new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(new MappingEntryCustomizer.MappingEntryDumpExecutor(jvppSnat)) + .build(); + + this.addressRangeDumpMgr = + new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(new ExternalIpPoolCustomizer.AddressRangeDumpExecutor(jvppSnat)) + .build(); } @Override diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java index 1aedba822..fb09e3a2e 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java @@ -19,6 +19,7 @@ package io.fd.honeycomb.translate.v3po.interfacesstate.ip; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; import com.google.common.base.Preconditions; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; @@ -26,6 +27,7 @@ import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; import io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.params.AddressDumpParams; import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; @@ -66,9 +68,12 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer @Nonnull final NamingContext interfaceContext) { super(futureJVppCore); this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(createExecutor(futureJVppCore)) - .build(); + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(createExecutor(futureJVppCore)) + // Key needs to contain interface ID to distinguish dumps between interfaces + .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(Interface.class))) + .build(); } @Override @@ -85,10 +90,8 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer final String interfaceName = id.firstKeyOf(Interface.class).getName(); final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); - // Key needs to contain interface ID to distinguish dumps between interfaces - final String cacheKey = CACHE_KEY + interfaceName; - final Optional dumpOptional = dumpManager - .getDump(id, cacheKey, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); + final Optional dumpOptional = + dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); if (!dumpOptional.isPresent() || dumpOptional.get().ipAddressDetails.isEmpty()) { return; @@ -116,10 +119,8 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer final String interfaceName = id.firstKeyOf(Interface.class).getName(); final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext()); - // Key needs to contain interface ID to distinguish dumps between interfaces - final String cacheKey = CACHE_KEY + interfaceName; - final Optional dumpOptional = dumpManager - .getDump(id, cacheKey, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); + final Optional dumpOptional = + dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); return getAllIpv4AddressIds(dumpOptional, AddressKey::new); } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java index 60171f768..a445c3f55 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java @@ -56,7 +56,6 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer implements InitializingListReaderCustomizer, Ipv4Reader { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class); - private static final String CACHE_KEY = SubInterfaceIpv4AddressCustomizer.class.getName(); private final NamingContext interfaceContext; private final DumpCacheManager dumpManager; @@ -85,7 +84,7 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); final Optional dumpOptional = dumpManager - .getDump(id, CACHE_KEY, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); + .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); final Optional ipAddressDetails = findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp()); @@ -110,7 +109,7 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()); final Optional dumpOptional = dumpManager - .getDump(id, CACHE_KEY, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); + .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); return getAllIpv4AddressIds(dumpOptional, AddressKey::new); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java index 42fae44a3..efe6c6afe 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java @@ -26,8 +26,11 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.honeycomb.translate.util.read.cache.CacheKeyFactory; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; import io.fd.honeycomb.translate.vpp.util.Ipv4Translator; import io.fd.honeycomb.translate.vpp.util.NamingContext; import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; @@ -67,6 +70,7 @@ public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest ifaceOneAddressOneIdentifier; private InstanceIdentifier
ifaceTwoAddressOneIdentifier; + private CacheKeyFactory cacheKeyFactory; public Ipv4AddressCustomizerTest() { super(Address.class, Ipv4Builder.class); @@ -90,6 +94,9 @@ public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest executor; - @Mock - private InstanceIdentifier identifier; + private InstanceIdentifier identifier; private DumpCacheManager managerPositive; private DumpCacheManager managerPositiveWithPostProcessing; private DumpCacheManager managerNegative; private ModificationCache cache; + private CacheKeyFactory cacheKeyFactory; @Before public void init() { @@ -57,10 +60,11 @@ public class DumpCacheManagerTest { .withExecutor(executor) .build(); - managerPositiveWithPostProcessing = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(executor) - .withPostProcessingFunction(createPostProcessor()) - .build(); + managerPositiveWithPostProcessing = + new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(executor) + .withPostProcessingFunction(createPostProcessor()) + .build(); managerNegative = new DumpCacheManager.DumpCacheManagerBuilder() @@ -68,6 +72,10 @@ public class DumpCacheManagerTest { .build(); cache = new ModificationCache(); + identifier = InstanceIdentifier.create(DataObj.class); + //manager uses this implementation by default, so it can be used to test behaviour + cacheKeyFactory = new IdentifierCacheKeyFactory(); + } /** @@ -76,24 +84,26 @@ public class DumpCacheManagerTest { @Test public void testCaching() throws ReadFailedException { final IpDetailsReplyDump stage1Data = new IpDetailsReplyDump(); + final String key = cacheKeyFactory.createKey(identifier); + // executor cant return null data when(executor.executeDump(identifier, NO_PARAMS)).thenReturn(new IpDetailsReplyDump()); - final Optional stage1Optional = managerNegative.getDump(identifier, KEY, cache, NO_PARAMS); + final Optional stage1Optional = managerNegative.getDump(identifier, cache, NO_PARAMS); // this is first call so instance should be from executor // and it should be cached after calling executor assertEquals(true, stage1Optional.isPresent()); assertEquals(stage1Data, stage1Optional.get()); - assertEquals(true, cache.containsKey(KEY)); - assertEquals(stage1Data, cache.get(KEY)); + assertEquals(true, cache.containsKey(key)); + assertEquals(stage1Data, cache.get(key)); //rebind executor with other data IpDetailsReplyDump stage2LoadedDump = new IpDetailsReplyDump(); when(executor.executeDump(identifier, NO_PARAMS)).thenReturn(stage2LoadedDump); - final Optional stage2Optional = managerPositive.getDump(identifier, KEY, cache, NO_PARAMS); + final Optional stage2Optional = managerPositive.getDump(identifier, cache, NO_PARAMS); assertEquals(true, stage2Optional.isPresent()); assertEquals(stage2LoadedDump, stage2Optional.get()); @@ -102,7 +112,7 @@ public class DumpCacheManagerTest { IpDetailsReplyDump stage3LoadedDump = new IpDetailsReplyDump(); when(executor.executeDump(identifier, NO_PARAMS)).thenReturn(stage3LoadedDump); - final Optional stage3Optional = managerPositive.getDump(identifier, KEY, cache, NO_PARAMS); + final Optional stage3Optional = managerPositive.getDump(identifier, cache, NO_PARAMS); assertEquals(true, stage3Optional.isPresent()); //check if it returns instance cached from previous stage assertEquals(stage2LoadedDump, stage3Optional.get()); @@ -118,7 +128,7 @@ public class DumpCacheManagerTest { when(executor.executeDump(identifier, null)).thenReturn(dump); Optional optionalDump = - managerPositiveWithPostProcessing.getDump(identifier, KEY, cache, NO_PARAMS); + managerPositiveWithPostProcessing.getDump(identifier, cache, NO_PARAMS); assertEquals(true, optionalDump.isPresent()); assertEquals(1, optionalDump.get().ipDetails.size()); -- cgit 1.2.3-korg