diff options
author | Jan Srnicek <jsrnicek@cisco.com> | 2016-11-03 09:37:28 +0100 |
---|---|---|
committer | Maros Marsalek <mmarsale@cisco.com> | 2016-11-03 10:51:24 +0000 |
commit | 03c9a24ebf7bee3ae767236b1fd3ae0ce8fccec6 (patch) | |
tree | 7f1c89590046858eb457585d4cb8412dda3d4aab | |
parent | 481fe32d90010b4570fd97239ca6c7940880d133 (diff) |
HONEYCOMB-259 - CacheKeyFactory
Provides logic for creating scoped keys
Change-Id: I126bcb9255b4f8a3f2585f50e6e718948581e7f0
Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
25 files changed, 459 insertions, 123 deletions
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<br> either from cache or by invoking specified {@link * EntityDumpExecutor} + * + * @param <T> Type of data returned by {@code EntityDumpExecutor},and stored cache + * @param <U> Type of dumping params */ public final class DumpCacheManager<T, U> { @@ -37,27 +40,29 @@ public final class DumpCacheManager<T, U> { private final EntityDumpExecutor<T, U> dumpExecutor; private final EntityDumpPostProcessingFunction<T> postProcessor; + private final CacheKeyFactory cacheKeyFactory; private DumpCacheManager(DumpCacheManagerBuilder<T, U> builder) { this.dumpExecutor = builder.dumpExecutor; this.postProcessor = builder.postProcessingFunction; + this.cacheKeyFactory = builder.cacheKeyFactory; } /** * Returns {@link Optional<T>} 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<T> getDump(@Nonnull final InstanceIdentifier<?> identifier, @Nonnull String entityKey, - @Nonnull ModificationCache cache, final U dumpParams) + public Optional<T> 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<T, U> { public static final class DumpCacheManagerBuilder<T, U> { + private static final CacheKeyFactory DEFAULT_CACHE_KEY_FACTORY_INSTANCE = new IdentifierCacheKeyFactory(); + private EntityDumpExecutor<T, U> dumpExecutor; private EntityDumpPostProcessingFunction<T> postProcessingFunction; + private CacheKeyFactory cacheKeyFactory; public DumpCacheManagerBuilder() { // for cases when user does not set specific post-processor postProcessingFunction = new NoopDumpPostProcessingFunction<T>(); + + //use no additional scopes version by default + cacheKeyFactory = DEFAULT_CACHE_KEY_FACTORY_INSTANCE; } - public DumpCacheManagerBuilder<T, U> withExecutor(@Nonnull EntityDumpExecutor<T, U> executor) { + public DumpCacheManagerBuilder<T, U> withExecutor(@Nonnull final EntityDumpExecutor<T, U> executor) { this.dumpExecutor = executor; return this; } public DumpCacheManagerBuilder<T, U> withPostProcessingFunction( - EntityDumpPostProcessingFunction<T> postProcessingFunction) { + @Nonnull final EntityDumpPostProcessingFunction<T> postProcessingFunction) { this.postProcessingFunction = postProcessingFunction; return this; } + public DumpCacheManagerBuilder<T, U> withCacheKeyFactory(@Nonnull final CacheKeyFactory cacheKeyFactory) { + this.cacheKeyFactory = cacheKeyFactory; + return this; + } + public DumpCacheManager<T, U> 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<Class<? extends DataObject & Identificable<?>>>, but that's not possible for wildcards + private final Set<Class<? extends DataObject>> 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<Class<? extends DataObject>> 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<? extends DataObject> verifyNotNull(final Class<? extends DataObject> 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<? extends DataObject> verifyIsIdentifiable(final Class<? extends DataObject> 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<SuperDataObject>, Identifiable<DataObjectParentKey> { + } + + private class DataObjectParentKey implements Identifier<DataObjectParent> { + } + + private interface DataObjectChild extends DataObject, ChildOf<DataObjectParent>, Identifiable<DataObjectChildKey> { + } + + private class DataObjectChildKey implements Identifier<DataObjectChild> { + } + + private DataObjectParentKey parentKey; + private DataObjectChildKey childKey; + private InstanceIdentifier<DataObjectChild> identifierBothKeyed; + private InstanceIdentifier<DataObjectChild> identifierOneMissing; + private InstanceIdentifier<DataObjectChild> 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<BridgeDomainSubtable, BridgeDomainSubtableBuilder>, SubtableReader { private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainSubtableCustomizer.class); - private static final String CACHE_KEY = BridgeDomainSubtableCustomizer.class.getName(); - private final DumpCacheManager<LispEidTableMapDetailsReplyDump, SubtableDumpParams> dumpManager; + private final DumpCacheManager<LispEidTableMapDetailsReplyDump, SubtableDumpParams> + dumpManager; private final NamingContext bridgeDomainContext; public BridgeDomainSubtableCustomizer(@Nonnull final FutureJVppCore futureJvppCore, @Nonnull final NamingContext bridgeDomainContext) { super(futureJvppCore); - dumpManager = new DumpCacheManagerBuilder<LispEidTableMapDetailsReplyDump, SubtableDumpParams>() - .withExecutor(createExecutor(futureJvppCore)) - .build(); + dumpManager = + new DumpCacheManagerBuilder<LispEidTableMapDetailsReplyDump, SubtableDumpParams>() + .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<LispEidTableMapDetailsReplyDump> 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<Interface, InterfaceKey, InterfaceBuilder>, LocatorReader { - private static final String KEY_BASE = InterfaceCustomizer.class.getName(); - private final NamingContext interfaceContext; private final NamingContext locatorSetContext; private final DumpCacheManager<LispLocatorDetailsReplyDump, LocatorDumpParams> dumpCacheManager; @@ -97,7 +95,7 @@ public class InterfaceCustomizer new LocatorDumpParamsBuilder().setLocatorSetIndex(locatorSetIndexIndex).build(); final Optional<LispLocatorDetailsReplyDump> 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<LispLocatorDetailsReplyDump> 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<ItrRemoteLocatorSet, ItrRemoteLocatorSetBuilder>, ByteDataTranslator, JvppReplyConsumer { - private static final String CACHE_KEY = ItrRemoteLocatorSetCustomizer.class.getName(); - private final DumpCacheManager<LispGetMapRequestItrRlocsReply, Void> dumpCacheManager; public ItrRemoteLocatorSetCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { @@ -68,7 +66,7 @@ public class ItrRemoteLocatorSetCustomizer extends FutureJVppCustomizer throws ReadFailedException { final Optional<LispGetMapRequestItrRlocsReply> 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<LispEidTableDetailsReplyDump, MappingsDumpParams> dumpManager; private final NamingContext locatorSetContext; @@ -113,7 +112,7 @@ public class LocalMappingCustomizer LOG.debug("Dumping data for LocalMappings(id={})", id); final Optional<LispEidTableDetailsReplyDump> 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<LispEidTableDetailsReplyDump> 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<? extends DataObject> builder, List<LocalMapping> 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<LocatorSet, LocatorSetKey, LocatorSetBuilder>, 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<LispLocatorSetDetailsReplyDump, Void> dumpManager; @@ -75,7 +74,7 @@ public class LocatorSetCustomizer extends FutureJVppCustomizer LOG.debug("Reading attributes for Locator Set {}", id); final Optional<LispLocatorSetDetailsReplyDump> 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<LispLocatorSetDetailsReplyDump> 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<LispMapResolverDetailsReplyDump, Void> dumpManager; public MapResolverCustomizer(FutureJVppCore futureJvpp) { super(futureJvpp); - this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<LispMapResolverDetailsReplyDump, Void>() - .withExecutor((identifier, params) -> getReplyForRead( - futureJvpp.lispMapResolverDump(new LispMapResolverDump()).toCompletableFuture(), identifier)) - .build(); + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder<LispMapResolverDetailsReplyDump, Void>() + .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<LispMapResolverDetailsReplyDump> 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<LispMapResolverDetailsReplyDump> 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<LispEidTableDetailsReplyDump, MappingsDumpParams> dumpManager; private final DumpCacheManager<LispLocatorDetailsReplyDump, LocatorDumpParams> 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<LispEidTableDetailsReplyDump, MappingsDumpParams>() .withExecutor(createMappingDumpExecutor(futureJvpp)) .build(); + + // cache key needs to have locator set scope to not mix with cached data this.locatorsDumpManager = new DumpCacheManager.DumpCacheManagerBuilder<LispLocatorDetailsReplyDump, LocatorDumpParams>() .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<LispEidTableDetailsReplyDump> 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<LispEidTableDetailsReplyDump> 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<LispLocatorDetailsReplyDump> reply; + + // this will serve to achieve that locators have locator set scope + final InstanceIdentifier<Interface> 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<LispEidTableVniDetailsReplyDump, Void> dumpManager; public VniTableCustomizer(@Nonnull final FutureJVppCore futureJvpp) { @@ -88,7 +87,7 @@ public class VniTableCustomizer extends FutureJVppCustomizer LOG.trace("Reading all IDS..."); final Optional<LispEidTableVniDetailsReplyDump> 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<LispEidTableVniDetailsReplyDump> 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<VrfSubtable, VrfSubtableBuilder>, SubtableReader { private static final Logger LOG = LoggerFactory.getLogger(VrfSubtableCustomizer.class); - private static final String CACHE_KEY = VrfSubtableCustomizer.class.getName(); private final DumpCacheManager<LispEidTableMapDetailsReplyDump, SubtableDumpParams> 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<LispEidTableMapDetailsReplyDump> reply = - readSubtable(dumpManager, CACHE_KEY, ctx.getModificationCache(), id, L3_PARAMS); + final Optional<LispEidTableMapDetailsReplyDump> 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<LispEidTableMapDetailsReplyDump> readSubtable( - @Nonnull final DumpCacheManager<LispEidTableMapDetailsReplyDump, SubtableDumpParams> dumpManager, - @Nonnull final String cacheKey, - @Nonnull final ModificationCache cache, - @Nonnull final InstanceIdentifier<? extends ChildOf<VniTable>> id, - @Nonnull final SubtableDumpParams params) throws ReadFailedException { - return dumpManager.getDump(id, cacheKey, cache, params); - } - default EntityDumpExecutor<LispEidTableMapDetailsReplyDump, SubtableDumpParams> 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<LispLocatorSetDetailsReplyDump, Void> 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<LispLocatorSetDetailsReplyDump, Void>() - .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<RemoteMapping, RemoteMappingBuilder> 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<SnatStaticMappingDetailsReplyDump, Void> dumpCacheManager; private final MappingEntryContext mappingEntryContext; - MappingEntryCustomizer(final DumpCacheManager<SnatStaticMappingDetailsReplyDump, Void> dumpCacheManager, - final MappingEntryContext mappingEntryContext) { + MappingEntryCustomizer( + final DumpCacheManager<SnatStaticMappingDetailsReplyDump, Void> 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<SnatStaticMappingDetails> 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<MappingEntryKey> 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<Na private final DumpCacheManager<SnatStaticMappingDetailsReplyDump, Void> dumpCacheManager; - NatInstanceCustomizer(final DumpCacheManager<SnatStaticMappingDetailsReplyDump, Void> dumpCacheManager) { + NatInstanceCustomizer( + final DumpCacheManager<SnatStaticMappingDetailsReplyDump, Void> dumpCacheManager) { this.dumpCacheManager = dumpCacheManager; } @@ -72,10 +73,10 @@ final class NatInstanceCustomizer implements InitializingListReaderCustomizer<Na // Find the nat instance IDs (vrf-ids) by listing all static mappings and their VRF assignment final List<NatInstanceKey> 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<NatState> NAT_OPER_ID = InstanceIdentifier.create(NatState.class); private static final InstanceIdentifier<NatInstances> NAT_INSTANCES_ID = NAT_OPER_ID.child(NatInstances.class); private static final InstanceIdentifier<NatInstance> NAT_INSTANCE_ID = NAT_INSTANCES_ID.child(NatInstance.class); - private static final InstanceIdentifier<NatCurrentConfig> CURRENT_CONFIG = NAT_INSTANCE_ID.child(NatCurrentConfig.class); + private static final InstanceIdentifier<NatCurrentConfig> CURRENT_CONFIG = + NAT_INSTANCE_ID.child(NatCurrentConfig.class); private static final InstanceIdentifier<MappingTable> MAP_TABLE_ID = NAT_INSTANCE_ID.child(MappingTable.class); private static final InstanceIdentifier<MappingEntry> MAP_ENTRY_ID = MAP_TABLE_ID.child(MappingEntry.class); @@ -55,16 +56,20 @@ public class NatReaderFactory implements ReaderFactory { private final DumpCacheManager<SnatStaticMappingDetailsReplyDump, Void> mapEntryDumpMgr; private final DumpCacheManager<SnatAddressDetailsReplyDump, Void> addressRangeDumpMgr; + @Inject public NatReaderFactory(final FutureJVppSnatFacade jvppSnat, final MappingEntryContext mappingEntryContext) { this.mappingEntryContext = mappingEntryContext; - this.mapEntryDumpMgr = new DumpCacheManager.DumpCacheManagerBuilder<SnatStaticMappingDetailsReplyDump, Void>() - .withExecutor(new MappingEntryCustomizer.MappingEntryDumpExecutor(jvppSnat)) - .build(); - this.addressRangeDumpMgr = new DumpCacheManager.DumpCacheManagerBuilder<SnatAddressDetailsReplyDump, Void>() - .withExecutor(new ExternalIpPoolCustomizer.AddressRangeDumpExecutor(jvppSnat)) - .build(); + this.mapEntryDumpMgr = + new DumpCacheManager.DumpCacheManagerBuilder<SnatStaticMappingDetailsReplyDump, Void>() + .withExecutor(new MappingEntryCustomizer.MappingEntryDumpExecutor(jvppSnat)) + .build(); + + this.addressRangeDumpMgr = + new DumpCacheManager.DumpCacheManagerBuilder<SnatAddressDetailsReplyDump, Void>() + .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<IpAddressDetailsReplyDump, AddressDumpParams>() - .withExecutor(createExecutor(futureJVppCore)) - .build(); + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder<IpAddressDetailsReplyDump, AddressDumpParams>() + .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<IpAddressDetailsReplyDump> dumpOptional = dumpManager - .getDump(id, cacheKey, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); + final Optional<IpAddressDetailsReplyDump> 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<IpAddressDetailsReplyDump> dumpOptional = dumpManager - .getDump(id, cacheKey, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false)); + final Optional<IpAddressDetailsReplyDump> 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<Address, AddressKey, AddressBuilder>, 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<IpAddressDetailsReplyDump, AddressDumpParams> 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<IpAddressDetailsReplyDump> dumpOptional = dumpManager - .getDump(id, CACHE_KEY, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); + .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false)); final Optional<IpAddressDetails> 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<IpAddressDetailsReplyDump> 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<Address, private NamingContext interfacesContext; private InstanceIdentifier<Address> ifaceOneAddressOneIdentifier; private InstanceIdentifier<Address> ifaceTwoAddressOneIdentifier; + private CacheKeyFactory cacheKeyFactory; public Ipv4AddressCustomizerTest() { super(Address.class, Ipv4Builder.class); @@ -90,6 +94,9 @@ public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest<Address, .augmentation(Interface2.class) .child(Ipv4.class) .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); + + // to simulate complex key + cacheKeyFactory = new IdentifierCacheKeyFactory(ImmutableSet.of(Interface.class)); } @Override @@ -258,8 +265,8 @@ public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest<Address, ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); detailIfaceTwoAddressOne.prefixLength = 23; - cache.put(Ipv4AddressCustomizer.class.getName() + IFACE_NAME, replyIfaceOne); - cache.put(Ipv4AddressCustomizer.class.getName() + IFACE_2_NAME, replyIfaceTwo); + cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); + cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), replyIfaceTwo); } private void fillCacheForFirstIfaceSecondEmpty() { @@ -271,7 +278,7 @@ public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest<Address, ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); detailIfaceOneAddressOne.prefixLength = 22; - cache.put(Ipv4AddressCustomizer.class.getName() + IFACE_NAME, replyIfaceOne); - cache.put(Ipv4AddressCustomizer.class.getName() + IFACE_2_NAME, new IpAddressDetailsReplyDump()); + cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); + cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), new IpAddressDetailsReplyDump()); } } diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/cache/DumpCacheManagerTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/cache/DumpCacheManagerTest.java index ac7dcece0..81a47e8a2 100644 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/cache/DumpCacheManagerTest.java +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/cache/DumpCacheManagerTest.java @@ -23,31 +23,34 @@ import static org.mockito.Mockito.when; import com.google.common.base.Optional; import io.fd.honeycomb.translate.ModificationCache; import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.util.read.cache.CacheKeyFactory; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; import io.fd.honeycomb.translate.util.read.cache.EntityDumpPostProcessingFunction; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; import io.fd.vpp.jvpp.core.dto.IpDetails; import io.fd.vpp.jvpp.core.dto.IpDetailsReplyDump; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class DumpCacheManagerTest { - private static final String KEY = "cacheKey"; + private interface DataObj extends DataObject {} @Mock private EntityDumpExecutor<IpDetailsReplyDump, Void> executor; - @Mock - private InstanceIdentifier identifier; + private InstanceIdentifier<DataObj> identifier; private DumpCacheManager<IpDetailsReplyDump, Void> managerPositive; private DumpCacheManager<IpDetailsReplyDump, Void> managerPositiveWithPostProcessing; private DumpCacheManager<IpDetailsReplyDump, Void> 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<IpDetailsReplyDump, Void>() - .withExecutor(executor) - .withPostProcessingFunction(createPostProcessor()) - .build(); + managerPositiveWithPostProcessing = + new DumpCacheManager.DumpCacheManagerBuilder<IpDetailsReplyDump, Void>() + .withExecutor(executor) + .withPostProcessingFunction(createPostProcessor()) + .build(); managerNegative = new DumpCacheManager.DumpCacheManagerBuilder<IpDetailsReplyDump, Void>() @@ -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<IpDetailsReplyDump> stage1Optional = managerNegative.getDump(identifier, KEY, cache, NO_PARAMS); + final Optional<IpDetailsReplyDump> 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<IpDetailsReplyDump> stage2Optional = managerPositive.getDump(identifier, KEY, cache, NO_PARAMS); + final Optional<IpDetailsReplyDump> 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<IpDetailsReplyDump> stage3Optional = managerPositive.getDump(identifier, KEY, cache, NO_PARAMS); + final Optional<IpDetailsReplyDump> 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<IpDetailsReplyDump> optionalDump = - managerPositiveWithPostProcessing.getDump(identifier, KEY, cache, NO_PARAMS); + managerPositiveWithPostProcessing.getDump(identifier, cache, NO_PARAMS); assertEquals(true, optionalDump.isPresent()); assertEquals(1, optionalDump.get().ipDetails.size()); |