Refactor data types cache
Avoids potential issue of data type cache changes by external parties,
by returning copies from the cache instead of the original.
Refactors the code for more clarity.
Change-Id: Ibb518bf638f2f4ee1f5e3869baaace374efb632a
Issue-ID: SDC-3569
Signed-off-by: André Schmid <andre.schmid@est.tech>
diff --git a/catalog-model/pom.xml b/catalog-model/pom.xml
index 17b1a0e..7666076 100644
--- a/catalog-model/pom.xml
+++ b/catalog-model/pom.xml
@@ -13,6 +13,10 @@
<version>1.9.0-SNAPSHOT</version>
</parent>
+ <properties>
+ <awaitility.version>4.0.3</awaitility.version>
+ </properties>
+
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
@@ -298,6 +302,13 @@
</dependency>
<dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <version>${awaitility.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
</dependency>
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java
index 6c28580..b61aa5a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java
@@ -37,17 +37,18 @@
private List<PropertyConstraint> constraints;
private List<PropertyDefinition> properties;
- public DataTypeDefinition(DataTypeDataDefinition p) {
- super(p);
+ public DataTypeDefinition(final DataTypeDataDefinition dataTypeDataDefinition) {
+ super(dataTypeDataDefinition);
}
- public DataTypeDefinition(DataTypeDefinition pd) {
- this.setName(pd.getName());
- this.setDerivedFrom(pd.getDerivedFrom());
- this.setDerivedFromName(pd.getDerivedFromName());
- this.setUniqueId(pd.getUniqueId());
- this.setConstraints(pd.getConstraints());
- this.setDescription(pd.getDescription());
+ public DataTypeDefinition(final DataTypeDefinition dataTypeDefinition) {
+ super(dataTypeDefinition);
+ this.setName(dataTypeDefinition.getName());
+ this.setDerivedFrom(dataTypeDefinition.getDerivedFrom());
+ this.setDerivedFromName(dataTypeDefinition.getDerivedFromName());
+ this.setUniqueId(dataTypeDefinition.getUniqueId());
+ this.setConstraints(dataTypeDefinition.getConstraints());
+ this.setDescription(dataTypeDefinition.getDescription());
}
public List<PropertyConstraint> safeGetConstraints() {
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java
index 4c58285..d0a0719 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java
@@ -25,7 +25,7 @@
public interface ApplicationCache<T> {
- public abstract Either<Map<String, T>, JanusGraphOperationStatus> getAll();
+ Either<Map<String, T>, JanusGraphOperationStatus> getAll();
- public abstract Either<T, JanusGraphOperationStatus> get(String uniqueId);
+ Either<T, JanusGraphOperationStatus> get(String uniqueId);
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java
index d6cc01b..a1bafbc 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java
@@ -20,36 +20,33 @@
package org.openecomp.sdc.be.model.cache;
import fj.data.Either;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
+import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
-import javax.annotation.Resource;
+import lombok.AccessLevel;
import lombok.Getter;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
-import org.apache.commons.lang3.tuple.ImmutablePair;
import org.openecomp.sdc.be.config.BeEcompErrorManager;
import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
-import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheConfig;
import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheInfo;
import org.openecomp.sdc.be.config.ConfigurationManager;
import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
import org.openecomp.sdc.be.resources.data.DataTypeData;
+import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
import org.openecomp.sdc.common.log.wrappers.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@@ -58,49 +55,68 @@
public class ApplicationDataTypeCache implements ApplicationCache<DataTypeDefinition>, Runnable {
private static final String APPLICATION_DATA_TYPES_CACHE = "ApplicationDataTypesCache";
- private static final Logger log = Logger.getLogger(ApplicationDataTypeCache.class.getName());
- private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
- private final Lock r = rwl.readLock();
- private final Lock w = rwl.writeLock();
- ScheduledFuture<?> scheduledFuture = null;
- private Map<String, DataTypeDefinition> data = new HashMap<>();
- private ScheduledExecutorService scheduledPollingService = Executors
- .newScheduledThreadPool(1, new BasicThreadFactory.Builder().namingPattern("ApplicationDataTypeCacheThread-%d").build());
+ private static final Logger log = Logger.getLogger(ApplicationDataTypeCache.class);
+
+ private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
+ private final PropertyOperation propertyOperation;
+ private final ApplicationEventPublisher applicationEventPublisher;
+ @Getter(AccessLevel.PACKAGE)
+ private final ScheduledExecutorService scheduledPollingService;
+ @Getter(AccessLevel.PACKAGE)
+ private ScheduledFuture<?> scheduledFuture = null;
+ private Map<String, DataTypeDefinition> dataTypesCacheMap = new HashMap<>();
private int firstRunDelayInSec = 30;
private int pollingIntervalInSec = 60;
- @Resource
- private PropertyOperation propertyOperation;
- @Autowired
- private ApplicationEventPublisher applicationEventPublisher;
+
+ public ApplicationDataTypeCache(final PropertyOperation propertyOperation, final ApplicationEventPublisher applicationEventPublisher) {
+ this.propertyOperation = propertyOperation;
+ this.applicationEventPublisher = applicationEventPublisher;
+ scheduledPollingService = Executors
+ .newScheduledThreadPool(1, new BasicThreadFactory.Builder().namingPattern("ApplicationDataTypeCacheThread-%d").build());
+ }
@PostConstruct
- public void init() {
- ApplicationL1CacheConfig applicationL1CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL1Cache();
- if (applicationL1CacheConfig != null) {
- if (applicationL1CacheConfig.getDatatypes() != null) {
- ApplicationL1CacheInfo datatypesInfo = applicationL1CacheConfig.getDatatypes();
- if (datatypesInfo.getEnabled()) {
- Integer intervalInSec = datatypesInfo.getPollIntervalInSec();
- if (intervalInSec != null) {
- pollingIntervalInSec = intervalInSec;
- }
- Integer firstRunDelay = datatypesInfo.getFirstRunDelay();
- if (firstRunDelay != null) {
- firstRunDelayInSec = firstRunDelay;
- }
- log.trace("ApplicationDataTypesCache polling interval is {} seconds.", pollingIntervalInSec);
- if (scheduledPollingService != null) {
- log.debug("Start ApplicationDataTypeCache polling task. polling interval {} seconds", pollingIntervalInSec);
- scheduledFuture = scheduledPollingService
- .scheduleAtFixedRate(this, firstRunDelayInSec, pollingIntervalInSec, TimeUnit.SECONDS);
- }
- }
- } else {
- BeEcompErrorManager.getInstance().logInternalFlowError(APPLICATION_DATA_TYPES_CACHE, "Cache is disabled", ErrorSeverity.INFO);
- }
- } else {
- BeEcompErrorManager.getInstance().logInternalFlowError(APPLICATION_DATA_TYPES_CACHE, "Cache is disabled", ErrorSeverity.INFO);
+ void init() {
+ final Optional<ApplicationL1CacheInfo> dataTypeCacheConfigOptional = getDataTypeCacheConfig();
+ if (dataTypeCacheConfigOptional.isEmpty()) {
+ BeEcompErrorManager.getInstance()
+ .logInternalFlowError(APPLICATION_DATA_TYPES_CACHE, "Data types cache is not configured and will be disabled", ErrorSeverity.INFO);
+ return;
}
+ final ApplicationL1CacheInfo dataTypesCacheInfo = dataTypeCacheConfigOptional.get();
+ if (!Boolean.TRUE.equals(dataTypesCacheInfo.getEnabled())) {
+ BeEcompErrorManager.getInstance().logInternalFlowError(APPLICATION_DATA_TYPES_CACHE, "Data types cache is disabled", ErrorSeverity.INFO);
+ return;
+ }
+ loadConfigurationValues(dataTypesCacheInfo);
+ if (scheduledPollingService != null) {
+ log.debug("Starting ApplicationDataTypeCache polling task. Initial delay {}s and polling interval {}s",
+ firstRunDelayInSec, pollingIntervalInSec);
+ scheduledFuture = scheduledPollingService
+ .scheduleAtFixedRate(this, firstRunDelayInSec, pollingIntervalInSec, TimeUnit.SECONDS);
+ }
+ }
+
+ private void loadConfigurationValues(final ApplicationL1CacheInfo dataTypesCacheInfo) {
+ final Integer firstRunDelay = dataTypesCacheInfo.getFirstRunDelay();
+ if (firstRunDelay != null) {
+ firstRunDelayInSec = firstRunDelay;
+ }
+ log.trace("ApplicationDataTypesCache initial delay configured to {} seconds.", firstRunDelayInSec);
+
+ final Integer intervalInSec = dataTypesCacheInfo.getPollIntervalInSec();
+ if (intervalInSec != null) {
+ pollingIntervalInSec = intervalInSec;
+ }
+ log.trace("ApplicationDataTypesCache polling interval configured to {} seconds.", pollingIntervalInSec);
+ }
+
+ private Optional<ApplicationL1CacheInfo> getDataTypeCacheConfig() {
+ final var applicationL1CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL1Cache();
+ if (applicationL1CacheConfig == null || applicationL1CacheConfig.getDatatypes() == null) {
+ return Optional.empty();
+ }
+ return Optional.ofNullable(applicationL1CacheConfig.getDatatypes());
}
@PreDestroy
@@ -147,138 +163,164 @@
@Override
public Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> getAll() {
try {
- r.lock();
- if (data == null || data.isEmpty()) {
+ readWriteLock.readLock().lock();
+ if (MapUtils.isEmpty(dataTypesCacheMap)) {
return getAllDataTypesFromGraph();
}
- return Either.left(data);
+ return Either.left(new HashMap<>(dataTypesCacheMap));
} finally {
- r.unlock();
+ readWriteLock.readLock().unlock();
}
}
@Override
public Either<DataTypeDefinition, JanusGraphOperationStatus> get(String uniqueId) {
try {
- r.lock();
- if (data == null || data.isEmpty()) {
+ readWriteLock.readLock().lock();
+ if (MapUtils.isEmpty(dataTypesCacheMap)) {
return propertyOperation.getDataTypeByUid(uniqueId);
- } else {
- DataTypeDefinition dataTypeDefinition = data.values().stream().filter(p -> p.getUniqueId().equals(uniqueId)).findFirst().orElse(null);
- if (dataTypeDefinition == null) {
- return propertyOperation.getDataTypeByUid(uniqueId);
- } else {
- return Either.left(dataTypeDefinition);
- }
}
+
+ final Optional<DataTypeDefinition> dataTypeDefinition = dataTypesCacheMap.values().stream()
+ .filter(p -> p.getUniqueId().equals(uniqueId)).findFirst();
+ if (dataTypeDefinition.isEmpty()) {
+ return propertyOperation.getDataTypeByUid(uniqueId);
+ }
+ return Either.left(new DataTypeDefinition(dataTypeDefinition.get()));
} finally {
- r.unlock();
+ readWriteLock.readLock().unlock();
}
}
@Override
public void run() {
- log.trace("run() method. polling db to fetch data types");
try {
- Long start = System.currentTimeMillis();
- log.trace("Start fetching all data types from db");
- Either<List<DataTypeData>, JanusGraphOperationStatus> allDataTypeNodes = propertyOperation.getAllDataTypeNodes();
- Long end = System.currentTimeMillis();
- log.trace("Finish fetching all data types from db. Took {} Milliseconds", (end - start));
- if (allDataTypeNodes.isRight()) {
- JanusGraphOperationStatus status = allDataTypeNodes.right().value();
- if (status != JanusGraphOperationStatus.OK) {
- log.debug("ApplicationDataTypesCache - Failed to fetch all data types nodes");
- BeEcompErrorManager.getInstance()
- .logInternalConnectionError("FetchDataTypes", "Failed to fetch data types from graph(cache)", ErrorSeverity.INFO);
- }
- } else {
- List<DataTypeData> list = allDataTypeNodes.left().value();
- if (list != null) {
- Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime = list.stream().collect(Collectors
- .toMap(p -> p.getDataTypeDataDefinition().getName(), p -> new ImmutablePair<>(p.getDataTypeDataDefinition().getCreationTime(),
- p.getDataTypeDataDefinition().getModificationTime())));
- Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime = new HashMap<>();
- try {
- r.lock();
- if (data != null) {
- currentDataTypeToModificationTime = data.values().stream().collect(Collectors
- .toMap(DataTypeDataDefinition::getName, p -> new ImmutablePair<>(p.getCreationTime(), p.getModificationTime())));
- }
- } finally {
- r.unlock();
- }
- boolean isChanged = compareDataTypes(dataTypeNameToModificationTime, currentDataTypeToModificationTime);
- if (isChanged) {
- replaceAllData();
- }
- }
+ final long startTime = System.currentTimeMillis();
+ log.trace("Starting refresh data types cache job");
+ if (hasDataTypesChanged()) {
+ log.info("Detected changes in the data types, updating the data type cache.");
+ refreshDataTypesCache();
}
- } catch (Exception e) {
- log.debug("unexpected error occured", e);
- BeEcompErrorManager.getInstance()
- .logInternalUnexpectedError(APPLICATION_DATA_TYPES_CACHE, "Failed to run refresh data types job", ErrorSeverity.INFO);
+ log.trace("Finished refresh data types cache job. Finished in {}ms", (System.currentTimeMillis() - startTime));
+ } catch (final Exception e) {
+ var errorMsg = "Failed to run refresh data types cache job";
+ log.error(EcompLoggerErrorCode.UNKNOWN_ERROR, ApplicationDataTypeCache.class.getName(), errorMsg, e);
+ BeEcompErrorManager.getInstance().logInternalUnexpectedError(APPLICATION_DATA_TYPES_CACHE, errorMsg, ErrorSeverity.INFO);
} finally {
try {
propertyOperation.getJanusGraphGenericDao().commit();
- } catch (Exception e) {
- log.trace("Failed to commit ApplicationDataTypeCache", e);
+ } catch (final Exception e) {
+ log.error(EcompLoggerErrorCode.UNKNOWN_ERROR, ApplicationDataTypeCache.class.getName(),
+ "Failed to commit ApplicationDataTypeCache", e);
}
}
}
- private boolean compareDataTypes(Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime,
- Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime) {
- if (dataTypeNameToModificationTime.size() != currentDataTypeToModificationTime.size()) {
+ private boolean hasDataTypesChanged() {
+ final List<DataTypeData> dataTypeListFromDatabase = findAllDataTypesLazy();
+ final Map<String, DataTypeDefinition> dataTypesCacheCopyMap = copyDataTypeCache();
+
+ if (dataTypeListFromDatabase.size() != dataTypesCacheCopyMap.size()) {
+ log.debug("Total of cached data types '{}' differs from the actual '{}'", dataTypeListFromDatabase.size(), dataTypesCacheCopyMap.size());
return true;
- } else {
- Set<String> currentkeySet = currentDataTypeToModificationTime.keySet();
- Set<String> keySet = dataTypeNameToModificationTime.keySet();
- if (currentkeySet.containsAll(keySet)) {
- for (Entry<String, ImmutablePair<Long, Long>> entry : dataTypeNameToModificationTime.entrySet()) {
- String dataTypeName = entry.getKey();
- ImmutablePair<Long, Long> creationAndModificationTimes = entry.getValue();
- long creationTime = creationAndModificationTimes.getLeft() == null ? 0 : creationAndModificationTimes.getLeft().longValue();
- long modificationTime = creationAndModificationTimes.getRight() == null ? 0 : creationAndModificationTimes.getRight().longValue();
- ImmutablePair<Long, Long> currentEntry = currentDataTypeToModificationTime.get(dataTypeName);
- long currentCreationTime = currentEntry.getLeft() == null ? 0 : currentEntry.getLeft().longValue();
- long currentModificationTime = currentEntry.getRight() == null ? 0 : currentEntry.getRight().longValue();
- if (creationTime > currentCreationTime || modificationTime > currentModificationTime) {
- log.debug("Datatype {} was updated. Creation Time {} vs {}. Modification Time {} vs {}", dataTypeName, currentCreationTime,
- creationTime, currentModificationTime, modificationTime);
- return true;
- }
- }
- } else {
+ }
+
+ if (CollectionUtils.isEmpty(dataTypeListFromDatabase)) {
+ log.debug("Both data type cache and database are empty");
+ return false;
+ }
+
+ return hasDataTypesChanged(dataTypeListFromDatabase, dataTypesCacheCopyMap);
+ }
+
+ private boolean hasDataTypesChanged(final List<DataTypeData> dataTypeListFromDatabase, final Map<String, DataTypeDefinition> dataTypesCacheCopyMap) {
+ return dataTypeListFromDatabase.stream().map(DataTypeData::getDataTypeDataDefinition).anyMatch(actualDataTypeDefinition -> {
+ final String dataTypeName = actualDataTypeDefinition.getName();
+ final DataTypeDefinition cachedDataTypeDefinition = dataTypesCacheCopyMap.get(dataTypeName);
+ if (cachedDataTypeDefinition == null) {
+ log.debug("Datatype '{}' is not present in the cache. ", dataTypeName);
return true;
}
- }
- return false;
- }
- private void replaceAllData() {
- Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = propertyOperation.getAllDataTypes();
- if (allDataTypes.isRight()) {
- JanusGraphOperationStatus status = allDataTypes.right().value();
- log.debug("Failed to fetch all data types from db. Status is {}", status);
- } else {
- try {
- w.lock();
- data = allDataTypes.left().value();
- // send notification on data types change
- onDataChangeEventEmit(data);
- BeEcompErrorManager.getInstance()
- .logInternalFlowError("ReplaceDataTypesCache", "Succeed to replace the data types cache", ErrorSeverity.INFO);
- } finally {
- w.unlock();
+ final long cachedCreationTime = cachedDataTypeDefinition.getCreationTime() == null ? 0 : cachedDataTypeDefinition.getCreationTime();
+ final long actualCreationTime = actualDataTypeDefinition.getCreationTime() == null ? 0 : actualDataTypeDefinition.getCreationTime();
+ if (cachedCreationTime != actualCreationTime) {
+ log.debug("Datatype '{}' was updated. Cache/database creation time '{}'/'{}'.",
+ dataTypeName, cachedCreationTime, actualCreationTime);
+ return true;
}
+ final long cachedModificationTime =
+ cachedDataTypeDefinition.getModificationTime() == null ? 0 : cachedDataTypeDefinition.getModificationTime();
+ final long actualModificationTime =
+ actualDataTypeDefinition.getModificationTime() == null ? 0 : actualDataTypeDefinition.getModificationTime();
+ if (cachedModificationTime != actualModificationTime) {
+ log.debug("Datatype '{}' was updated. Cache/database modification time '{}'/'{}'.",
+ dataTypeName, cachedModificationTime, actualModificationTime);
+ return true;
+ }
+
+ return false;
+ });
+ }
+
+ private Map<String, DataTypeDefinition> copyDataTypeCache() {
+ try {
+ readWriteLock.readLock().lock();
+ return new HashMap<>(this.dataTypesCacheMap);
+ } finally {
+ readWriteLock.readLock().unlock();
}
}
- private void onDataChangeEventEmit(Map<String, DataTypeDefinition> newData) {
- log.trace("Cache data has changed, sending event to all listening for this change.");
- DataTypesCacheChangedEvent dataTypesCacheChangedEvent = new DataTypesCacheChangedEvent(this, newData);
- applicationEventPublisher.publishEvent(dataTypesCacheChangedEvent);
+ private void refreshDataTypesCache() {
+ final Map<String, DataTypeDefinition> dataTypesDefinitionMap = findAllDataTypesEager();
+ if (dataTypesDefinitionMap.isEmpty()) {
+ return;
+ }
+ try {
+ readWriteLock.writeLock().lock();
+ dataTypesCacheMap = dataTypesDefinitionMap;
+ onDataChangeEventEmit();
+ BeEcompErrorManager.getInstance()
+ .logInternalFlowError("ReplaceDataTypesCache", "Succeed to replace the data types cache", ErrorSeverity.INFO);
+ } finally {
+ readWriteLock.writeLock().unlock();
+ }
+ }
+
+ private Map<String, DataTypeDefinition> findAllDataTypesEager() {
+ log.trace("Fetching data types from database, eager mode");
+ final long startTime = System.currentTimeMillis();
+ final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = propertyOperation.getAllDataTypes();
+ log.trace("Finish fetching data types from database. Took {}ms", (System.currentTimeMillis() - startTime));
+ if (allDataTypes.isRight()) {
+ final JanusGraphOperationStatus status = allDataTypes.right().value();
+ var errorMsg= String.format("Failed to fetch data types from database. Status is %s", status);
+ log.error(EcompLoggerErrorCode.UNKNOWN_ERROR, ApplicationDataTypeCache.class.getName(), errorMsg);
+ BeEcompErrorManager.getInstance().logInternalConnectionError(APPLICATION_DATA_TYPES_CACHE, errorMsg, ErrorSeverity.ERROR);
+ return Collections.emptyMap();
+ }
+ return allDataTypes.left().value();
+ }
+
+ private List<DataTypeData> findAllDataTypesLazy() {
+ log.trace("Fetching data types from database, lazy mode");
+ final long startTime = System.currentTimeMillis();
+ final Either<List<DataTypeData>, JanusGraphOperationStatus> allDataTypes = propertyOperation.getAllDataTypeNodes();
+ log.trace("Finish fetching data types from database. Took {}ms", (System.currentTimeMillis() - startTime));
+ if (allDataTypes.isRight()) {
+ final JanusGraphOperationStatus status = allDataTypes.right().value();
+ var errorMsg= String.format("Failed to fetch data types from database. Status is %s", status);
+ log.error(EcompLoggerErrorCode.UNKNOWN_ERROR, ApplicationDataTypeCache.class.getName(), errorMsg);
+ BeEcompErrorManager.getInstance().logInternalConnectionError(APPLICATION_DATA_TYPES_CACHE, errorMsg, ErrorSeverity.ERROR);
+ return Collections.emptyList();
+ }
+ return allDataTypes.left().value();
+ }
+
+ private void onDataChangeEventEmit() {
+ log.trace("Data type cache has changed, sending DataTypesCacheChangedEvent.");
+ applicationEventPublisher.publishEvent(new DataTypesCacheChangedEvent(this, copyDataTypeCache()));
}
/**
@@ -287,11 +329,12 @@
public static class DataTypesCacheChangedEvent extends ApplicationEvent {
@Getter
- private Map<String, DataTypeDefinition> newData;
+ private final Map<String, DataTypeDefinition> newData;
- public DataTypesCacheChangedEvent(Object source, Map<String, DataTypeDefinition> newData) {
+ public DataTypesCacheChangedEvent(final Object source, final Map<String, DataTypeDefinition> newData) {
super(source);
this.newData = newData;
}
}
+
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java
index 1592782..db379f5 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java
@@ -42,7 +42,6 @@
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.IComplexDefaultValue;
import org.openecomp.sdc.be.model.PropertyConstraint;
-import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser;
import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
@@ -60,8 +59,6 @@
@Autowired
protected HealingJanusGraphGenericDao janusGraphGenericDao;
protected Gson gson = new Gson();
- @Autowired
- protected ApplicationDataTypeCache applicationDataTypeCache;
protected DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
public <ElementDefinition> JanusGraphOperationStatus findAllResourceElementsDefinitionRecursively(String resourceId,
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java
index 7906467..0632364 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java
@@ -1562,14 +1562,10 @@
}
public Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypeNodes() {
- Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypes = janusGraphGenericDao
- .getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
- if (getAllDataTypes.isRight()) {
- JanusGraphOperationStatus status = getAllDataTypes.right().value();
- if (status == JanusGraphOperationStatus.NOT_FOUND) {
- status = JanusGraphOperationStatus.OK;
- return Either.right(status);
- }
+ final Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypes =
+ janusGraphGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
+ if (getAllDataTypes.isRight() && getAllDataTypes.right().value() == JanusGraphOperationStatus.NOT_FOUND) {
+ return Either.left(Collections.emptyList());
}
return getAllDataTypes;
}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCacheTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCacheTest.java
index 7186d2a..9126b64 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCacheTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCacheTest.java
@@ -7,9 +7,9 @@
* 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.
@@ -20,175 +20,281 @@
package org.openecomp.sdc.be.model.cache;
+import static org.awaitility.Awaitility.await;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
import fj.data.Either;
-import mockit.Deencapsulation;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.junit.Before;
-import org.junit.Test;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.config.Configuration;
+import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheConfig;
+import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheInfo;
+import org.openecomp.sdc.be.config.ConfigurationManager;
import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
import org.openecomp.sdc.be.resources.data.DataTypeData;
-import org.openecomp.sdc.be.unittests.utils.ModelConfDependentTest;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
import org.springframework.context.ApplicationEventPublisher;
-public class ApplicationDataTypeCacheTest extends ModelConfDependentTest{
+class ApplicationDataTypeCacheTest {
- @InjectMocks
- private ApplicationDataTypeCache testSubject;
-
- @Mock
- PropertyOperation propertyOperation;
+ @Mock
+ private PropertyOperation propertyOperation;
- @Mock
- ApplicationEventPublisher applicationEventPublisher;
+ @Mock
+ private ApplicationEventPublisher applicationEventPublisher;
- @Before
- public void setUpMocks() throws Exception {
- MockitoAnnotations.initMocks(this);
+ @InjectMocks
+ private ApplicationDataTypeCache applicationDataTypeCache;
+
+ private Map<String, DataTypeDefinition> dataTypeDefinitionMap;
+
+ private int schedulerFirstRunDelay = 0;
+ private int schedulerPollIntervalInSec = 2;
+ private boolean schedulerIsEnabled = true;
+
+ @BeforeEach
+ public void beforeEach() {
+ MockitoAnnotations.openMocks(this);
}
+ @AfterEach
+ public void afterEach() {
+ final ScheduledExecutorService scheduledPollingService = applicationDataTypeCache.getScheduledPollingService();
+ if (scheduledPollingService == null) {
+ return;
+ }
- @Test
- public void testInit() throws Exception {
- testSubject.init();
+ if (scheduledPollingService.isShutdown()) {
+ return;
+ }
+
+ scheduledPollingService.shutdownNow();
}
@Test
- public void testDestroy() throws Exception {
- testSubject.init();
- Deencapsulation.invoke(testSubject, "destroy");
+ void testInitSuccess() {
+ defaultInit();
+ assertNotNull(applicationDataTypeCache.getScheduledFuture(), "The job should have been triggered");
}
@Test
- public void testShutdownExecutor() throws Exception {
-
- // default test
- Deencapsulation.invoke(testSubject, "shutdownExecutor");
+ void testDestroySuccess() {
+ defaultInit();
+ assertNotNull(applicationDataTypeCache.getScheduledFuture(), "The job should have been triggered");
+ applicationDataTypeCache.destroy();
+ assertNull(applicationDataTypeCache.getScheduledFuture(), "The job should have been stopped");
+ assertTrue(applicationDataTypeCache.getScheduledPollingService().isShutdown(), "The scheduler should have been stopped");
}
@Test
- public void testGetAllDataTypesFromGraph() throws Exception {
- Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> result;
-
- // default test
- result = Deencapsulation.invoke(testSubject, "getAllDataTypesFromGraph");
+ void testDestroyWithoutSchedulerInitialization() {
+ mockEmptyConfiguration();
+ applicationDataTypeCache.init();
+ assertNotNull(applicationDataTypeCache.getScheduledPollingService(), "The scheduler should have been created");
+ assertFalse(applicationDataTypeCache.getScheduledPollingService().isShutdown(), "The scheduler should have been running");
+ assertNull(applicationDataTypeCache.getScheduledFuture(), "The job should not have been triggered");
+ applicationDataTypeCache.destroy();
+ assertTrue(applicationDataTypeCache.getScheduledPollingService().isShutdown(), "The scheduler should have been stopped");
}
@Test
- public void testGetAll() throws Exception {
- Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> result;
-
- // default test
- result = testSubject.getAll();
+ void testInitEmptyConfiguration() {
+ mockEmptyConfiguration();
+ applicationDataTypeCache.init();
+ assertNull(applicationDataTypeCache.getScheduledFuture(), "The scheduler should not have started");
}
@Test
- public void testGet() throws Exception {
- String uniqueId = "";
- Either<DataTypeDefinition, JanusGraphOperationStatus> result;
-
- // default test
- result = testSubject.get(uniqueId);
+ void testInitCacheDisabled() {
+ final var applicationL1CacheInfo = new ApplicationL1CacheInfo();
+ applicationL1CacheInfo.setEnabled(false);
+ mockConfiguration(applicationL1CacheInfo);
+ applicationDataTypeCache.init();
+ assertNull(applicationDataTypeCache.getScheduledFuture(), "The scheduler should not have started");
}
@Test
- public void testGet2() throws Exception {
- String uniqueId = "";
- Either<DataTypeDefinition, JanusGraphOperationStatus> result;
-
- HashMap<String, DataTypeDefinition> a = new HashMap<>();
- DataTypeDefinition value1 = new DataTypeDefinition();
- value1.setUniqueId("mock");
- a.put("mock", value1);
- Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> value = Either.left(a);
- Mockito.when(propertyOperation.getAllDataTypes()).thenReturn(value);
- // default test
- Deencapsulation.invoke(testSubject, "replaceAllData");
- result = testSubject.get(uniqueId);
- }
-
- @Test
- public void testRun() throws Exception {
- testSubject.run();
+ void testGetAllAfterInitialization() {
+ defaultInit();
+ final ScheduledFuture<?> scheduledFuture = applicationDataTypeCache.getScheduledFuture();
+ //waiting the cache to be filled
+ await().atMost(Duration.ofSeconds(schedulerPollIntervalInSec + 1)).until(() -> scheduledFuture.getDelay(TimeUnit.SECONDS) != 0);
+ assertDataTypeCache(dataTypeDefinitionMap);
}
@Test
- public void testRun2() throws Exception {
- Either<List<DataTypeData>, JanusGraphOperationStatus> value = Either.right(
- JanusGraphOperationStatus.GENERAL_ERROR);
- Mockito.when(propertyOperation.getAllDataTypeNodes()).thenReturn(value);
- testSubject.run();
- }
-
- @Test
- public void testRun3() throws Exception {
- LinkedList<DataTypeData> a = new LinkedList<>();
- a.add(new DataTypeData());
- Either<List<DataTypeData>, JanusGraphOperationStatus> value = Either.left(a);
- Mockito.when(propertyOperation.getAllDataTypeNodes()).thenReturn(value);
-
- HashMap<String, DataTypeDefinition> a1 = new HashMap<>();
- DataTypeDefinition value1 = new DataTypeDefinition();
- value1.setUniqueId("mock");
- a1.put("mock", value1);
- Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> value2 = Either.left(a1);
- Mockito.when(propertyOperation.getAllDataTypes()).thenReturn(value2);
-
- Deencapsulation.invoke(testSubject, "replaceAllData");
- testSubject.run();
- }
-
- @Test
- public void testCompareDataTypes() throws Exception {
- Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime = new HashMap<>();
- Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime = new HashMap<>();
- boolean result;
+ void testCacheChangeWithDataTypeChange() {
+ defaultInit();
+ final ScheduledFuture<?> scheduledFuture = applicationDataTypeCache.getScheduledFuture();
+ //waiting the cache to be filled
+ await().atMost(Duration.ofSeconds(schedulerPollIntervalInSec + 1)).until(() -> scheduledFuture.getDelay(TimeUnit.SECONDS) != 0);
+ assertDataTypeCache(dataTypeDefinitionMap);
- // default test
- result = Deencapsulation.invoke(testSubject, "compareDataTypes", dataTypeNameToModificationTime, currentDataTypeToModificationTime);
+ final DataTypeDefinition testDataType1 = createDataTypeDefinition("test.data.type1", "test.data.type1", 101L, 1000L);
+ final DataTypeDefinition testDataType2 = createDataTypeDefinition("test.data.type2", "test.data.type2", 101L, 1002L);
+ final Map<String, DataTypeDefinition> modifiedDataTypeDefinitionMap =
+ Map.of(testDataType1.getName(), testDataType1, testDataType2.getName(), testDataType2);
+ when(propertyOperation.getAllDataTypes()).thenReturn(Either.left(modifiedDataTypeDefinitionMap));
+
+ final DataTypeData dataTypeData1 = createDataTypeData("test.data.type1", "test.data.type1", 101L, 101L);
+ final DataTypeData dataTypeData2 = createDataTypeData("test.data.type2", "test.data.type2", 101L, 1002L);
+
+ when(propertyOperation.getAllDataTypeNodes()).thenReturn(Either.left(List.of(dataTypeData1, dataTypeData2)));
+
+ await().atMost(Duration.ofSeconds(schedulerPollIntervalInSec + 1)).until(() -> scheduledFuture.getDelay(TimeUnit.SECONDS) == 0);
+ await().atMost(Duration.ofSeconds(schedulerPollIntervalInSec + 1)).until(() -> scheduledFuture.getDelay(TimeUnit.SECONDS) != 0);
+ assertDataTypeCache(modifiedDataTypeDefinitionMap);
}
@Test
- public void testCompareDataTypes2() throws Exception {
- Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime = new HashMap<>();
- Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime = new HashMap<>();
- boolean result;
-
- currentDataTypeToModificationTime.put("mock", ImmutablePair.of(1L, 2L));
- dataTypeNameToModificationTime.put("mock", ImmutablePair.of(5L, 6L));
-
- // default test
- result = Deencapsulation.invoke(testSubject, "compareDataTypes", dataTypeNameToModificationTime, currentDataTypeToModificationTime);
+ void testCacheChangeWithAddedDataType() {
+ defaultInit();
+ final ScheduledFuture<?> scheduledFuture = applicationDataTypeCache.getScheduledFuture();
+ //waiting the cache to be filled
+ await().until(() -> scheduledFuture.getDelay(TimeUnit.SECONDS) != 0);
+ assertDataTypeCache(dataTypeDefinitionMap);
+
+ final Map<String, DataTypeDefinition> modifiedDataTypeDefinitionMap = new HashMap<>();
+ final DataTypeDefinition testDataType1 = createDataTypeDefinition("test.data.type1", "test.data.type1", 1L, 1L);
+ modifiedDataTypeDefinitionMap.put(testDataType1.getName(), testDataType1);
+ final DataTypeDefinition testDataType3 = createDataTypeDefinition("test.data.type3", "test.data.type3", 1L, 1L);
+ modifiedDataTypeDefinitionMap.put(testDataType3.getName(), testDataType3);
+ when(propertyOperation.getAllDataTypes()).thenReturn(Either.left(modifiedDataTypeDefinitionMap));
+
+ final DataTypeData dataTypeData1 = createDataTypeData("test.data.type1", "test.data.type1", 1L, 1L);
+ final DataTypeData dataTypeData3 = createDataTypeData("test.data.type3", "test.data.type3", 1L, 1L);
+
+ when(propertyOperation.getAllDataTypeNodes()).thenReturn(Either.left(List.of(dataTypeData1, dataTypeData3)));
+
+ await().atMost(Duration.ofSeconds(schedulerPollIntervalInSec + 1)).until(() -> scheduledFuture.getDelay(TimeUnit.SECONDS) == 0);
+ await().atMost(Duration.ofSeconds(schedulerPollIntervalInSec + 1)).until(() -> scheduledFuture.getDelay(TimeUnit.SECONDS) != 0);
+ assertDataTypeCache(modifiedDataTypeDefinitionMap);
}
-
+
@Test
- public void testReplaceAllData() throws Exception {
- HashMap<String, DataTypeDefinition> a = new HashMap<>();
- DataTypeDefinition value1 = new DataTypeDefinition();
- value1.setUniqueId("mock");
- a.put("mock", value1);
- Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> value = Either.left(a);
- Mockito.when(propertyOperation.getAllDataTypes()).thenReturn(value);
- // default test
- Deencapsulation.invoke(testSubject, "replaceAllData");
+ void testGetAllWithNoInitialization() {
+ final Map<String, DataTypeDefinition> dataTypeDefinitionMap = new HashMap<>();
+ when(propertyOperation.getAllDataTypes()).thenReturn(Either.left(dataTypeDefinitionMap));
+ final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> response = applicationDataTypeCache.getAll();
+ assertNotNull(response);
+ assertTrue(response.isLeft());
}
-
+
@Test
- public void testReplaceAllData2() throws Exception {
- Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> value = Either.right(
- JanusGraphOperationStatus.GENERAL_ERROR);
- Mockito.when(propertyOperation.getAllDataTypes()).thenReturn(value);
- // default test
- Deencapsulation.invoke(testSubject, "replaceAllData");
+ void testGetWhenCacheIsEmpty() {
+ var dataTypeDefinition = new DataTypeDefinition();
+ when(propertyOperation.getDataTypeByUid("uniqueId")).thenReturn(Either.left(dataTypeDefinition));
+ final Either<DataTypeDefinition, JanusGraphOperationStatus> dataTypeEither = applicationDataTypeCache.get("uniqueId");
+ assertNotNull(dataTypeEither);
+ assertTrue(dataTypeEither.isLeft());
+ assertEquals(dataTypeDefinition, dataTypeEither.left().value());
+ }
+
+ @Test
+ void testGetCacheHit() {
+ defaultInit();
+ final ScheduledFuture<?> scheduledFuture = applicationDataTypeCache.getScheduledFuture();
+ await().atMost(Duration.ofSeconds(schedulerPollIntervalInSec + 1)).until(() -> scheduledFuture.getDelay(TimeUnit.SECONDS) != 0);
+ final Either<DataTypeDefinition, JanusGraphOperationStatus> dataTypeEither = applicationDataTypeCache.get("test.data.type1");
+ assertNotNull(dataTypeEither);
+ assertTrue(dataTypeEither.isLeft());
+ final DataTypeDefinition actualDataTypeDefinition = dataTypeEither.left().value();
+ final DataTypeDefinition expectedDataTypeDefinition = dataTypeDefinitionMap.get("test.data.type1");
+ assertEquals(expectedDataTypeDefinition.getName(), actualDataTypeDefinition.getName());
+ assertEquals(expectedDataTypeDefinition.getUniqueId(), actualDataTypeDefinition.getUniqueId());
+ assertEquals(expectedDataTypeDefinition.getCreationTime(), actualDataTypeDefinition.getCreationTime());
+ assertEquals(expectedDataTypeDefinition.getModificationTime(), actualDataTypeDefinition.getModificationTime());
+ }
+
+ private void defaultInit() {
+ var applicationL1CacheInfo = new ApplicationL1CacheInfo();
+ applicationL1CacheInfo.setEnabled(schedulerIsEnabled);
+ applicationL1CacheInfo.setFirstRunDelay(schedulerFirstRunDelay);
+ applicationL1CacheInfo.setPollIntervalInSec(schedulerPollIntervalInSec);
+ mockConfiguration(applicationL1CacheInfo);
+
+ dataTypeDefinitionMap = new HashMap<>();
+ final DataTypeDefinition testDataType1 = createDataTypeDefinition("test.data.type1", "test.data.type1", 100L, 1000L);
+ dataTypeDefinitionMap.put(testDataType1.getName(), testDataType1);
+ final DataTypeDefinition testDataType2 = createDataTypeDefinition("test.data.type2", "test.data.type2", 101L, 1001L);
+ dataTypeDefinitionMap.put(testDataType2.getName(), testDataType2);
+ when(propertyOperation.getAllDataTypes()).thenReturn(Either.left(dataTypeDefinitionMap));
+
+ final DataTypeData dataTypeData1 = createDataTypeData("test.data.type1", testDataType1.getName(), 100L, 1000L);
+ final DataTypeData dataTypeData2 = createDataTypeData("test.data.type2", testDataType2.getName(), 101L, 1001L);
+
+ when(propertyOperation.getAllDataTypeNodes()).thenReturn(Either.left(List.of(dataTypeData1, dataTypeData2)));
+ applicationDataTypeCache.init();
+ }
+
+ private DataTypeDefinition createDataTypeDefinition(String name, String uniqueId, long creationTime, long modificationTime) {
+ final DataTypeDefinition dataTypeDefinition = new DataTypeDefinition();
+ dataTypeDefinition.setName(name);
+ dataTypeDefinition.setUniqueId(uniqueId);
+ dataTypeDefinition.setCreationTime(creationTime);
+ dataTypeDefinition.setModificationTime(modificationTime);
+ return dataTypeDefinition;
+ }
+
+ private DataTypeData createDataTypeData(String name, String uniqueId, long creationTime, long modificationTime) {
+ final DataTypeData dataTypeData1 = new DataTypeData();
+ dataTypeData1.setDataTypeDataDefinition(createDataTypeDataDefinition(name, uniqueId, creationTime, modificationTime));
+ return dataTypeData1;
+ }
+ private DataTypeDataDefinition createDataTypeDataDefinition(String name, String uniqueId, long creationTime, long modificationTime) {
+ final DataTypeDataDefinition testDataType1DataDefinition = new DataTypeDataDefinition();
+ testDataType1DataDefinition.setName(name);
+ testDataType1DataDefinition.setUniqueId(uniqueId);
+ testDataType1DataDefinition.setCreationTime(creationTime);
+ testDataType1DataDefinition.setModificationTime(modificationTime);
+ return testDataType1DataDefinition;
+ }
+
+ private void mockConfiguration(final ApplicationL1CacheInfo applicationL1CacheInfo) {
+ final var applicationL1CacheConfig = new ApplicationL1CacheConfig();
+ applicationL1CacheConfig.setDatatypes(applicationL1CacheInfo);
+ final var configuration = new Configuration();
+ configuration.setApplicationL1Cache(applicationL1CacheConfig);
+ final var configurationManager = new ConfigurationManager();
+ configurationManager.setConfiguration(configuration);
+ }
+
+ private void mockEmptyConfiguration() {
+ final var applicationL1CacheConfig = new ApplicationL1CacheConfig();
+ final var configuration = new Configuration();
+ configuration.setApplicationL1Cache(applicationL1CacheConfig);
+ final var configurationManager = new ConfigurationManager();
+ configurationManager.setConfiguration(configuration);
+ }
+
+ public void assertDataTypeCache(final Map<String, DataTypeDefinition> expectedDataTypeCache) {
+ Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypeCacheMapEither = applicationDataTypeCache.getAll();
+ assertNotNull(dataTypeCacheMapEither);
+ assertTrue(dataTypeCacheMapEither.isLeft());
+ final Map<String, DataTypeDefinition> actualDataTypeMap = dataTypeCacheMapEither.left().value();
+ expectedDataTypeCache.forEach((dataType, dataTypeDefinition) -> {
+ final DataTypeDefinition actualDataTypeDefinition = actualDataTypeMap.get(dataType);
+ assertNotNull(actualDataTypeDefinition);
+ assertEquals(dataTypeDefinition.getCreationTime(), actualDataTypeDefinition.getCreationTime());
+ assertEquals(dataTypeDefinition.getModificationTime(), actualDataTypeDefinition.getModificationTime());
+ });
}
}