From c5b4c5afe8047a4e39434b9416c995f62daba64b Mon Sep 17 00:00:00 2001 From: GCHQDeveloper314 <94527357+GCHQDeveloper314@users.noreply.github.com> Date: Tue, 12 Mar 2024 15:10:16 +0000 Subject: [PATCH] Gh-3094: Allow services to use different cache implementations (#3147) * Change CacheServiceLoader to support multiple caches and change Store and Properties classes to use these * Modify Federated Store to work with new cache approach. Includes removing redundant inheritance from FederatedStoreCache. * Fix Federated Store tests. Mostly changes to use FederatedStoreProperties instead of general properties and remove usage of empty properties * Fix checking of deprecated property. Also allow new property in deprecated method * Remove use of old CacheServiceLoader initialise method from tests * Remove use of deprecated CacheServiceLoader getService method from tests * Replace use of deprecated CacheServiceLoader.isEnabled * Remove direct use of Cache Service from FederatedGraphStorage Also fix missing generics in Cache.java * Replace use of deprecated CACHE_SERVICE_CLASS field * Remove duplicate field identical to existing field and use static import instead * Deprecated old CacheServiceLoader Test * Rename old CacheServiceLoader Test * Add new test for CacheServiceLoader Change log4j test settings for cache module to show DEBUG messages * Improve warning for when a subgraph tries to set cache class The previous approach replaced the class but this wasn't required as re-initialising was already ignored. Now it warns with more details. * Replace use of old default cache class property in all properties files * Replace use of deprecated cache service class setter method * Improve Javadoc for Federated Store Cache classes * Remove duplicate cache class string fields in Federated Store tests * Remove unreachable code relating to missing cache class in Federated Store Improve handling to set the missing cache property instead of behaving as if it was * Move all cache properties into CacheProperties.java * Improve test coverage for new changes * Add test to cover separate cache initialisation in Store * Fix Store.java typo and improve logic * Simplify FederatedStorePropertiesTest * PR Comment - Use only AssertJ in CacheTest.java * Fix changes * Fix typo * PR Comment - Remove 'public' from new unit test class methods * Add new field to Store containing cache interface objects These can be used to access these caches without repeatly recreating the Cache objects elsewhere or trying to get the Service directly * Change FederatedGraphStorage to get caches from Store instead of creating them and add a new test for multiple cache instances --- .../java/uk/gov/gchq/gaffer/cache/Cache.java | 34 +- .../gchq/gaffer/cache/CacheServiceLoader.java | 150 ++++++- .../gaffer/cache/util/CacheProperties.java | 36 +- .../gaffer/cache/CacheServiceLoaderTest.java | 131 ++++-- .../uk/gov/gchq/gaffer/cache/CacheTest.java | 66 ++- .../DeprecatedCacheServiceLoaderTest.java | 94 ++++ core/cache/src/test/resources/log4j.xml | 2 +- .../java/uk/gov/gchq/gaffer/graph/Graph.java | 4 + .../named/cache/NamedOperationCacheIT.java | 15 +- .../gchq/gaffer/jobtracker/JobTracker.java | 4 +- .../jobtracker/JobTrackerBrokenCacheTest.java | 8 +- .../java/uk/gov/gchq/gaffer/store/Store.java | 58 ++- .../gchq/gaffer/store/StoreProperties.java | 69 ++- .../named/cache/NamedOperationCache.java | 3 +- .../handler/named/cache/NamedViewCache.java | 4 +- .../gaffer/store/StorePropertiesTest.java | 400 ++++++++++++++++-- .../uk/gov/gchq/gaffer/store/StoreTest.java | 63 ++- .../named/AddNamedViewHandlerTest.java | 11 +- .../named/DeleteNamedViewHandlerTest.java | 7 +- .../GetAllNamedOperationsHandlerTest.java | 4 +- .../named/GetAllNamedViewsHandlerTest.java | 24 +- .../named/cache/NamedOperationCacheTest.java | 6 +- ...medViewCacheBackwardCompatibilityTest.java | 6 +- .../named/cache/NamedViewCacheTest.java | 6 +- .../src/test/resources/allCaches.properties | 21 + .../src/test/resources/legacyStore.properties | 16 + .../src/test/resources/suffixes.properties | 19 + .../src/main/resources/map/store.properties | 2 +- .../main/resources/federatedStore.properties | 2 +- .../src/main/resources/map/store.properties | 2 +- .../test/resources/accumulo/store.properties | 2 +- .../src/test/resources/map/store.properties | 2 +- .../resources/gaffer/map-store.properties | 2 +- .../src/test/resources/store.properties | 2 +- .../persistent-caching-store.properties | 2 +- .../src/test/resources/store.properties | 2 +- .../src/main/resources/map/store.properties | 2 +- .../controller/JobControllerIT.java | 8 +- .../controller/OperationControllerIT.java | 5 +- .../accumuloStoreClassicKeys.properties | 2 +- .../src/test/resources/cache-store.properties | 2 +- .../src/test/resources/store.properties | 2 +- .../federatedstore/FederatedGraphStorage.java | 41 +- .../gaffer/federatedstore/FederatedStore.java | 22 +- .../federatedstore/FederatedStoreCache.java | 15 +- .../FederatedStoreCacheTransient.java | 7 +- .../FederatedStoreProperties.java | 14 +- .../FederatedAddGraphHandlerParent.java | 54 ++- .../AdminGetAllGraphInfoTest.java | 5 +- ...atedAccessResourceAccessPredicateTest.java | 6 +- .../FederatedGraphStorageTest.java | 35 +- .../FederatedStoreAuthTest.java | 4 +- ...edStoreCacheBackwardCompatibilityTest.java | 6 +- .../FederatedStoreCacheSuffixTest.java | 30 +- .../FederatedStoreCacheTest.java | 8 +- .../FederatedStoreGetWalksTest.java | 4 +- .../FederatedStoreGraphLibraryTest.java | 4 +- .../FederatedStoreGraphVisibilityTest.java | 4 +- .../FederatedStoreMultiCacheTest.java | 4 +- .../FederatedStorePropertiesTest.java | 113 +++++ .../FederatedStorePublicAccessTest.java | 4 +- .../FederatedStoreSchemaTest.java | 3 +- .../federatedstore/FederatedStoreTest.java | 51 +-- .../FederatedStoreTestUtil.java | 7 +- .../FederatedStoreToFederatedStoreTest.java | 5 +- .../FederatedStoreVisibilityTest.java | 4 +- .../FederatedStoreWrongGraphIDsTest.java | 6 +- .../FederatedStoreFileGraphLibraryIT.java | 3 +- .../impl/FederatedAddGraphHandlerTest.java | 6 +- ...FederatedAddGraphWithHooksHandlerTest.java | 6 +- .../impl/FederatedGetTraitsHandlerTest.java | 27 +- .../FederatedOperationChainHandlerTest.java | 8 +- .../impl/FederatedRemoveGraphHandlerTest.java | 114 +++-- .../impl/FederatedUnhandledOperationTest.java | 4 +- ...ederatedStoreConfiguredGraphIds.properties | 2 +- ...nfiguredGraphIdsFailFileInvalid.properties | 2 +- ...nfiguredGraphIdsFailPathMissing.properties | 2 +- ...cAccessPredefinedFederatedStore.properties | 2 +- .../predefinedFederatedStore.properties | 2 +- .../properties/federatedStore.properties | 18 + ...cAccessPredefinedFederatedStore.properties | 2 +- .../src/test/resources/store.properties | 2 +- .../src/test/resources/map-store.properties | 2 +- 83 files changed, 1450 insertions(+), 508 deletions(-) create mode 100644 core/cache/src/test/java/uk/gov/gchq/gaffer/cache/DeprecatedCacheServiceLoaderTest.java create mode 100644 core/store/src/test/resources/allCaches.properties create mode 100644 core/store/src/test/resources/legacyStore.properties create mode 100644 core/store/src/test/resources/suffixes.properties create mode 100644 store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStorePropertiesTest.java create mode 100644 store-implementation/federated-store/src/test/resources/properties/federatedStore.properties diff --git a/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/Cache.java b/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/Cache.java index 43fc534d866..2dedf354e9f 100644 --- a/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/Cache.java +++ b/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/Cache.java @@ -24,6 +24,7 @@ import java.util.stream.StreamSupport; import static java.util.Objects.nonNull; +import static uk.gov.gchq.gaffer.cache.CacheServiceLoader.DEFAULT_SERVICE_NAME; /** * Type safe cache, adding and getting is guaranteed to be same type. @@ -32,9 +33,22 @@ */ public class Cache { protected String cacheName; + private final String serviceName; + + public Cache(final String cacheName, final String serviceName) { + this.cacheName = cacheName; + // Use the supplied cache service name if it exists, otherwise + // fallback to the default cache service name + if (CacheServiceLoader.isEnabled(serviceName)) { + this.serviceName = serviceName; + } else { + this.serviceName = DEFAULT_SERVICE_NAME; + } + } public Cache(final String cacheName) { this.cacheName = cacheName; + this.serviceName = DEFAULT_SERVICE_NAME; } /** @@ -44,7 +58,7 @@ public Cache(final String cacheName) { * @throws CacheOperationException if issue getting from cache */ public V getFromCache(final String key) throws CacheOperationException { - return CacheServiceLoader.getService().getFromCache(cacheName, key); + return CacheServiceLoader.getService(serviceName).getFromCache(cacheName, key); } public String getCacheName() { @@ -62,7 +76,7 @@ public String getCacheName() { * cache */ protected void addToCache(final K key, final V value, final boolean overwrite) throws CacheOperationException { - final ICacheService service = CacheServiceLoader.getService(); + final ICacheService service = CacheServiceLoader.getService(serviceName); if (overwrite) { service.putInCache(getCacheName(), key, value); } else { @@ -73,10 +87,10 @@ protected void addToCache(final K key, final V value, final boolean overwrite) t public Iterable getAllKeys() { try { final Iterable allKeysFromCache; - if (CacheServiceLoader.isEnabled()) { - allKeysFromCache = CacheServiceLoader.getService().getAllKeysFromCache(cacheName); + if (CacheServiceLoader.isEnabled(serviceName)) { + allKeysFromCache = CacheServiceLoader.getService(serviceName).getAllKeysFromCache(cacheName); } else { - throw new GafferRuntimeException("Cache is not enabled, check it was Initialised"); + throw new GafferRuntimeException(String.format("Cache '%s' is not enabled, check it was initialised", serviceName)); } return (null == allKeysFromCache) ? Collections.emptySet() : allKeysFromCache; } catch (final Exception e) { @@ -90,7 +104,7 @@ public Iterable getAllKeys() { * @throws CacheOperationException if there was an error trying to clear the cache */ public void clearCache() throws CacheOperationException { - CacheServiceLoader.getService().clearCache(cacheName); + CacheServiceLoader.getService(serviceName).clearCache(cacheName); } public boolean contains(final String graphId) { @@ -104,7 +118,7 @@ public boolean contains(final String graphId) { * @param key the ID of the key to be deleted */ public void deleteFromCache(final String key) { - CacheServiceLoader.getService().removeFromCache(cacheName, key); + CacheServiceLoader.getService(serviceName).removeFromCache(cacheName, key); } /** @@ -112,9 +126,9 @@ public void deleteFromCache(final String key) { * * @return ICache */ - public ICache getCache() { - if (CacheServiceLoader.getService() != null) { - return CacheServiceLoader.getService().getCache(cacheName); + public ICache getCache() { + if (CacheServiceLoader.isEnabled(serviceName)) { + return CacheServiceLoader.getService(serviceName).getCache(cacheName); } else { return null; } diff --git a/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/CacheServiceLoader.java b/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/CacheServiceLoader.java index 90a42ac5248..9fb559cf119 100644 --- a/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/CacheServiceLoader.java +++ b/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/CacheServiceLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 Crown Copyright + * Copyright 2016-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,14 @@ package uk.gov.gchq.gaffer.cache; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.gov.gchq.gaffer.cache.util.CacheProperties; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; /** @@ -32,44 +34,140 @@ public final class CacheServiceLoader { private static final Logger LOGGER = LoggerFactory.getLogger(CacheServiceLoader.class); - private static ICacheService service; + public static final String DEFAULT_SERVICE_NAME = "default"; + private static final Map SERVICES = new HashMap<>(); private static boolean shutdownHookAdded = false; + /** + * Creates a cache service identified by the given service name, using the supplied class + * name and properties to initialise the service. + *

Adds a shutdown hook which gracefully closes the cache service if JVM is stopped. + * This shouldn't be relied upon in a servlet context, instead use ServletLifecycleListener. + * + * @param serviceName name to identify the cache service to initialise + * @param cacheClass class name of the cache service provider to use + * @param properties properties to pass to the cache service provider + * @throws IllegalArgumentException if an invalid cache class is specified + */ + public static void initialise(final String serviceName, final String cacheClass, final Properties properties) { + if (isEnabled(serviceName)) { + LOGGER.debug("Will not initialise as Cache service '{}' was already enabled.", serviceName); + return; + } + + if (cacheClass == null) { + throw new IllegalArgumentException("Failed to instantiate cache, cache class was null/missing"); + } else if (serviceName == null) { + throw new IllegalArgumentException("Failed to instantiate cache, service name was null/missing"); + } + + try { + Class newCacheClass = Class.forName(cacheClass).asSubclass(ICacheService.class); + ICacheService newCacheInstance = newCacheClass.getDeclaredConstructor().newInstance(); + SERVICES.put(serviceName, newCacheInstance); + } catch (final InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { + throw new IllegalArgumentException("Failed to instantiate cache using class " + cacheClass, e); + } catch (final ClassNotFoundException | ClassCastException e) { + throw new IllegalArgumentException(String.format("Failed to instantiate cache, class '%s' is missing or invalid", cacheClass), e); + } + + SERVICES.get(serviceName).initialise(properties); + + if (!shutdownHookAdded) { + Runtime.getRuntime().addShutdownHook(new Thread(CacheServiceLoader::shutdown)); + shutdownHookAdded = true; + } + } + + /** + * Creates a default cache service using the supplied class name to initialise the service. + * No properties are passed to the cache service, this is primarily a convenience method. + * See {@link #initialise(String, String, Properties)} for further details. + * + * @param cacheClass class name of the cache service provider to use + * @throws IllegalArgumentException if an invalid cache class is specified + */ + public static void initialise(final String cacheClass) { + initialise(DEFAULT_SERVICE_NAME, cacheClass, null); + } + + /** + * Get the default cache service object. + * + * @return the default cache service + */ + public static ICacheService getDefaultService() { + return SERVICES.get(DEFAULT_SERVICE_NAME); + } + + /** + * Get the cache service identified by the supplied name. + * + * @param serviceName name identifying the cache service + * @return the cache service + */ + public static ICacheService getService(final String serviceName) { + return SERVICES.get(serviceName); + } + + /** + * @return true if the default cache service is enabled + */ + public static boolean isDefaultEnabled() { + return SERVICES.containsKey(DEFAULT_SERVICE_NAME); + } + + /** + * @param serviceName name identifying a cache service + * @return true if a cache service with that name exists (and is therefore enabled) + */ + public static boolean isEnabled(final String serviceName) { + return SERVICES.containsKey(serviceName); + } + /** * Looks at a system property and initialises an appropriate cache service. Adds a shutdown hook * which gracefully closes the cache service if JVM is stopped. This should not be relied upon - * in a servlet context - use the ServletLifecycleListener located in the REST module instead + * in a servlet context - use the ServletLifecycleListener located in the REST module instead. + * @deprecated Instead use {@link #initialise(String, String, Properties)}, or optionally + * {@link #initialise(String)} when writing tests. * * @param properties the cache service properties * @throws IllegalArgumentException if an invalid cache class is specified in the system property */ + @Deprecated public static void initialise(final Properties properties) { + LOGGER.warn("Calling the deprecated initialise method initialises the default cache service, " + + "this will cause problems if you are using service specific cache services"); if (null == properties) { LOGGER.warn("received null properties - exiting initialise method without creating service"); return; } - final String cacheClass = properties.getProperty(CacheProperties.CACHE_SERVICE_CLASS); + final String cacheClass = (properties.getProperty(CacheProperties.CACHE_SERVICE_DEFAULT_CLASS) != null) ? + properties.getProperty(CacheProperties.CACHE_SERVICE_DEFAULT_CLASS) : + properties.getProperty(CacheProperties.CACHE_SERVICE_CLASS); if (null == cacheClass) { - if (null == service) { - LOGGER.debug("No cache service class was specified in properties."); - } + LOGGER.debug("No cache service class was specified in properties."); return; } - if (isEnabled()) { + if (isDefaultEnabled()) { LOGGER.debug("Will not initialise as Cache service was already enabled."); return; } try { - service = Class.forName(cacheClass).asSubclass(ICacheService.class).newInstance(); - - } catch (final InstantiationException | IllegalAccessException | ClassNotFoundException e) { + Class newCacheClass = Class.forName(cacheClass).asSubclass(ICacheService.class); + ICacheService newCacheInstance = newCacheClass.getDeclaredConstructor().newInstance(); + SERVICES.put(DEFAULT_SERVICE_NAME, newCacheInstance); + } catch (final InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { throw new IllegalArgumentException("Failed to instantiate cache using class " + cacheClass, e); + } catch (final ClassNotFoundException | ClassCastException e) { + throw new IllegalArgumentException(String.format("Failed to instantiate cache, class '%s' is invalid", cacheClass), e); } - service.initialise(properties); + SERVICES.get(DEFAULT_SERVICE_NAME).initialise(properties); if (!shutdownHookAdded) { Runtime.getRuntime().addShutdownHook(new Thread(CacheServiceLoader::shutdown)); @@ -78,31 +176,41 @@ public static void initialise(final Properties properties) { } /** - * Get the cache service object. + * Get the default cache service object. + * @deprecated Cache services should instead be + * fetched by name using {@link #getService(String)}, + * or by using {@link #getDefaultService()}. * - * @return the cache service + * @return the default cache service */ - @SuppressFBWarnings(value = "MS_EXPOSE_REP", justification = "Intended behaviour") + @Deprecated public static ICacheService getService() { - return service; + LOGGER.warn("Calling the deprecated getService method returns the default cache service, " + + "this will cause problems if you are using service specific cache services"); + return getDefaultService(); } /** - * @return true if the cache is enabled + * @return true if the default cache is enabled + * @deprecated Use {@link #isDefaultEnabled()} instead, + * or {@link #isEnabled(String)} with a service name. */ + @Deprecated public static boolean isEnabled() { - return null != service; + LOGGER.warn("Calling the deprecated isEnabled method only returns if the default cache service " + + "is enabled, this will cause problems if you are using service specific cache services"); + return isDefaultEnabled(); } /** * Gracefully shutdown and reset the cache service. */ public static void shutdown() { - if (null != service) { + for (final ICacheService service: SERVICES.values()) { service.shutdown(); } - service = null; + SERVICES.clear(); } private CacheServiceLoader() { diff --git a/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/util/CacheProperties.java b/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/util/CacheProperties.java index 66256699719..863d785e36c 100644 --- a/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/util/CacheProperties.java +++ b/core/cache/src/main/java/uk/gov/gchq/gaffer/cache/util/CacheProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 Crown Copyright + * Copyright 2016-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,10 +26,42 @@ private CacheProperties() { } /** - * Name of the system property to use in order to define the cache service class. + * Name of a system property previously used for defining the default cache service class. + * @deprecated Use {@link #CACHE_SERVICE_DEFAULT_CLASS} instead. */ + @Deprecated public static final String CACHE_SERVICE_CLASS = "gaffer.cache.service.class"; + /** + * Name of the system property to use for defining the default cache service class. + */ + public static final String CACHE_SERVICE_DEFAULT_CLASS = "gaffer.cache.service.default.class"; + + /** + * Name of the system property to use for defining a cache service class dedicated to the Job Tracker. + */ + public static final String CACHE_SERVICE_JOB_TRACKER_CLASS = "gaffer.cache.service.jobtracker.class"; + + /** + * Name of the system property to use for defining a cache service class dedicated to Named Views. + */ + public static final String CACHE_SERVICE_NAMED_VIEW_CLASS = "gaffer.cache.service.namedview.class"; + + /** + * Name of the system property to use for defining a cache service class dedicated to Named Operations. + */ + public static final String CACHE_SERVICE_NAMED_OPERATION_CLASS = "gaffer.cache.service.namedoperation.class"; + + /** + * Names of the system properties used to set the suffix for all caches or per cache. + * CASE INSENSITIVE + * e.g. gaffer.cache.service.default.suffix="v2" + */ + public static final String CACHE_SERVICE_DEFAULT_SUFFIX = "gaffer.cache.service.default.suffix"; + public static final String CACHE_SERVICE_NAMED_OPERATION_SUFFIX = "gaffer.cache.service.named.operation.suffix"; + public static final String CACHE_SERVICE_JOB_TRACKER_SUFFIX = "gaffer.cache.service.job.tracker.suffix"; + public static final String CACHE_SERVICE_NAMED_VIEW_SUFFIX = "gaffer.cache.service.named.view.suffix"; + /** * Name of the system property to use in order to locate the cache config file. */ diff --git a/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/CacheServiceLoaderTest.java b/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/CacheServiceLoaderTest.java index ae7c0b6c104..93b47f4ba19 100644 --- a/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/CacheServiceLoaderTest.java +++ b/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/CacheServiceLoaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 Crown Copyright + * Copyright 2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,73 +17,124 @@ package uk.gov.gchq.gaffer.cache; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import uk.gov.gchq.gaffer.cache.impl.HashMapCacheService; -import uk.gov.gchq.gaffer.cache.util.CacheProperties; - import java.util.Properties; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; public class CacheServiceLoaderTest { - - private Properties serviceLoaderProperties = new Properties(); + private final Properties emptyProperties = new Properties(); + private final String emptyCacheServiceName = "emptyService"; + private final String emptyCacheServiceClass = EmptyCacheService.class.getName(); @BeforeEach - public void before() { - serviceLoaderProperties.clear(); + void reset() { CacheServiceLoader.shutdown(); } - @DisplayName("Should not throw NullPointer when Loader is initialised with null properties") @Test - public void shouldINotThrowNullPointerExceptionOnInitialiseLoader() { - CacheServiceLoader.initialise(null); + void shouldInitialiseWithNameClassAndProperties() { + // When + CacheServiceLoader.initialise(emptyCacheServiceName, emptyCacheServiceClass, emptyProperties); + + // Then + assertThat(CacheServiceLoader.getService(emptyCacheServiceName)).isNotNull(); } @Test - public void shouldLoadServiceFromSystemVariable() { - serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, EmptyCacheService.class.getName()); - CacheServiceLoader.initialise(serviceLoaderProperties); - - final ICacheService service = CacheServiceLoader.getService(); + void shouldInitialiseWithOnlyClass() { + // When + CacheServiceLoader.initialise(emptyCacheServiceClass); - assertThat(service).isInstanceOf(EmptyCacheService.class); + // Then + assertThat(CacheServiceLoader.getDefaultService()).isNotNull(); } @Test - public void shouldThrowAnExceptionWhenSystemVariableIsInvalid() { - final String invalidClassName = "invalid.cache.name"; - serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, invalidClassName); - - assertThatIllegalArgumentException() - .isThrownBy(() -> CacheServiceLoader.initialise(serviceLoaderProperties)) - .withMessage("Failed to instantiate cache using class invalid.cache.name"); + void shouldInitialiseOnceOnlyWithSameServiceName() { + // Given + CacheServiceLoader.initialise(emptyCacheServiceClass); + final ICacheService initialService = CacheServiceLoader.getDefaultService(); + + // When + // Should have no effect as the default service was already initialized + CacheServiceLoader.initialise(emptyCacheServiceClass); + + // Then + // Should reference exactly the same object, proving it was not overwritten + assertThat(CacheServiceLoader.getDefaultService()).isSameAs(initialService); } @Test - public void shouldUseTheSameServiceAcrossDifferentComponents() { - serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); - CacheServiceLoader.initialise(serviceLoaderProperties); + void shouldThrowExceptionWhenInitialisingWithNullClass() { + // When / Then + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CacheServiceLoader.initialise(emptyCacheServiceName, null, emptyProperties)) + .withMessage("Failed to instantiate cache, cache class was null/missing"); + } - final ICacheService component1Service = CacheServiceLoader.getService(); - final ICacheService component2Service = CacheServiceLoader.getService(); + @Test + void shouldThrowExceptionWhenInitialisingWithNullName() { + // When / Then + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CacheServiceLoader.initialise(null, emptyCacheServiceClass, emptyProperties)) + .withMessage("Failed to instantiate cache, service name was null/missing"); + } - assertEquals(component1Service, component2Service); + @Test + void shouldThrowExceptionWhenInitialisingWithMissingClass() { + // When / Then + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CacheServiceLoader.initialise(emptyCacheServiceName, "a.class.which.does.not.exist", emptyProperties)) + .withMessage("Failed to instantiate cache, class 'a.class.which.does.not.exist' is missing or invalid"); } @Test - public void shouldSetServiceToNullAfterCallingShutdown() { - serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, EmptyCacheService.class.getName()); - CacheServiceLoader.initialise(serviceLoaderProperties); + void shouldThrowExceptionWhenInitialisingWithInvalidClass() { + // When / Then + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CacheServiceLoader.initialise(emptyCacheServiceName, ICacheService.class.getName(), emptyProperties)) + .withMessage("Failed to instantiate cache using class uk.gov.gchq.gaffer.cache.ICacheService"); + } - CacheServiceLoader.shutdown(); + @Test + void shouldGetServiceEnabledBooleans() { + // Given + // Nothing initialised + + // When / Then + assertThat(CacheServiceLoader.isDefaultEnabled()).isFalse(); + assertThat(CacheServiceLoader.isEnabled(emptyCacheServiceName)).isFalse(); + + // Given + // Initialise empty & default services + CacheServiceLoader.initialise(emptyCacheServiceName, emptyCacheServiceClass, emptyProperties); + CacheServiceLoader.initialise(emptyCacheServiceClass); + + // When / Then + assertThat(CacheServiceLoader.isDefaultEnabled()).isTrue(); + assertThat(CacheServiceLoader.isEnabled(emptyCacheServiceName)).isTrue(); + } - assertNull(CacheServiceLoader.getService()); + @Test + void shouldGetServices() { + // Given + // Nothing initialised + + // When / Then + assertThat(CacheServiceLoader.getDefaultService()).isNull(); + assertThat(CacheServiceLoader.getService(emptyCacheServiceName)).isNull(); + + // Given + // Initialise empty & default services + CacheServiceLoader.initialise(emptyCacheServiceName, emptyCacheServiceClass, emptyProperties); + CacheServiceLoader.initialise(emptyCacheServiceClass); + + // When / Then + assertThat(CacheServiceLoader.getDefaultService()).isInstanceOf(EmptyCacheService.class).isNotNull(); + assertThat(CacheServiceLoader.getService(emptyCacheServiceName)).isInstanceOf(EmptyCacheService.class).isNotNull(); + assertThat(CacheServiceLoader.getDefaultService()).isNotSameAs(CacheServiceLoader.getService(emptyCacheServiceName)); } } diff --git a/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/CacheTest.java b/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/CacheTest.java index 5c34099406a..36cf68235eb 100644 --- a/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/CacheTest.java +++ b/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/CacheTest.java @@ -16,35 +16,27 @@ package uk.gov.gchq.gaffer.cache; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import uk.gov.gchq.gaffer.cache.exception.CacheOperationException; -import uk.gov.gchq.gaffer.cache.util.CacheProperties; import uk.gov.gchq.gaffer.commonutil.exception.OverwritingException; +import java.util.Collections; import java.util.Properties; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; class CacheTest { - private static final String CACHE_SERVICE_CLASS_STRING = "uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"; private static Cache cache; - private static Properties properties = new Properties(); - - @BeforeAll - static void setUp() { - properties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, CACHE_SERVICE_CLASS_STRING); - CacheServiceLoader.initialise(properties); - cache = new Cache<>("serviceName1"); - } @BeforeEach - void beforeEach() throws CacheOperationException { - cache.clearCache(); + void beforeEach() { + CacheServiceLoader.shutdown(); + CacheServiceLoader.initialise(CACHE_SERVICE_CLASS_STRING); + cache = new Cache<>("cacheName1"); } @Test @@ -69,19 +61,59 @@ void shouldAddAndGetCacheNoOverwrite() throws CacheOperationException { assertThatExceptionOfType(OverwritingException.class) .isThrownBy(() -> cache.addToCache("key1", 2, false)) - .withMessageContaining("Cache entry already exists for key: key1"); - assertThat(cache.getFromCache("key1").intValue()).isEqualTo(1); + .withMessage("Cache entry already exists for key: key1"); + assertThat(cache.getFromCache("key1")).isEqualTo(1); } @Test - void shouldGetCacheServiceName() { - assertThat(cache.getCacheName()).isEqualTo("serviceName1"); + void shouldGetCacheName() { + assertThat(cache.getCacheName()).isEqualTo("cacheName1"); } @Test void shouldDeleteKeyValuePair() throws CacheOperationException { cache.addToCache("key1", 1, false); cache.deleteFromCache("key1"); + assertThat(cache.getFromCache("key1")).isNull(); } + + @Test + void shouldGetAllKeys() throws CacheOperationException { + assertThat(cache.getAllKeys()).isEqualTo(Collections.emptySet()); + cache.addToCache("key1", 1, false); + assertThat(cache.getAllKeys()).isEqualTo(Collections.singleton("key1")); + } + + @Test + void shouldThrowExceptionTryingToGetAllKeysWhenNoServiceAvailable() { + CacheServiceLoader.shutdown(); + assertThatExceptionOfType(uk.gov.gchq.gaffer.core.exception.GafferRuntimeException.class) + .isThrownBy(() -> cache.getAllKeys()) + .withMessage("Error getting all keys") + .withStackTraceContaining("is not enabled, check it was initialised"); + } + + @Test + void shouldConstructCacheWithCacheAndServiceName() { + final String serviceName = "myService"; + final String cacheName = "myCache"; + // Using the default service + Cache tmpCache = new Cache<>(cacheName, serviceName); + assertThat(tmpCache.getCacheName()).isEqualTo(cacheName); + + // Using new service with name "myService" + CacheServiceLoader.shutdown(); + CacheServiceLoader.initialise(serviceName, CACHE_SERVICE_CLASS_STRING, new Properties()); + Cache tmpCache2 = new Cache<>(cacheName, serviceName); + assertThat(tmpCache2.getCacheName()).isEqualTo(cacheName); + } + + @Test + void shouldGetICache() { + assertThat(cache.getCache().getClass().getName()).isEqualTo(CACHE_SERVICE_CLASS_STRING.replaceAll("Service", "")); + CacheServiceLoader.shutdown(); + assertThat(cache.getCache()).isNull(); + } } + diff --git a/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/DeprecatedCacheServiceLoaderTest.java b/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/DeprecatedCacheServiceLoaderTest.java new file mode 100644 index 00000000000..0a5c101b71a --- /dev/null +++ b/core/cache/src/test/java/uk/gov/gchq/gaffer/cache/DeprecatedCacheServiceLoaderTest.java @@ -0,0 +1,94 @@ +/* + * Copyright 2017-2024 Crown Copyright + * + * 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 uk.gov.gchq.gaffer.cache; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import uk.gov.gchq.gaffer.cache.impl.HashMapCacheService; +import uk.gov.gchq.gaffer.cache.util.CacheProperties; + +import java.util.Properties; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * This class tests only deprecated parts of + * {@link CacheServiceLoader}. When these parts + * are removed this class can be removed. + */ +@Deprecated +public class DeprecatedCacheServiceLoaderTest { + private final Properties serviceLoaderProperties = new Properties(); + + @BeforeEach + public void before() { + serviceLoaderProperties.clear(); + CacheServiceLoader.shutdown(); + } + + @DisplayName("Should not throw NullPointer when Loader is initialised with null properties") + @Test + public void shouldINotThrowNullPointerExceptionOnInitialiseLoader() { + CacheServiceLoader.initialise((Properties) null); + } + + @Test + public void shouldLoadServiceFromSystemVariable() { + serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, EmptyCacheService.class.getName()); + CacheServiceLoader.initialise(serviceLoaderProperties); + + final ICacheService service = CacheServiceLoader.getService(); + + assertThat(service).isInstanceOf(EmptyCacheService.class); + } + + @Test + public void shouldThrowAnExceptionWhenSystemVariableIsInvalid() { + final String invalidClassName = "invalid.cache.name"; + serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, invalidClassName); + + assertThatIllegalArgumentException() + .isThrownBy(() -> CacheServiceLoader.initialise(serviceLoaderProperties)) + .withMessage("Failed to instantiate cache, class 'invalid.cache.name' is invalid"); + } + + @Test + public void shouldUseTheSameServiceAcrossDifferentComponents() { + serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); + CacheServiceLoader.initialise(serviceLoaderProperties); + + final ICacheService component1Service = CacheServiceLoader.getService(); + final ICacheService component2Service = CacheServiceLoader.getService(); + + assertEquals(component1Service, component2Service); + } + + @Test + public void shouldSetServiceToNullAfterCallingShutdown() { + serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, EmptyCacheService.class.getName()); + CacheServiceLoader.initialise(serviceLoaderProperties); + + CacheServiceLoader.shutdown(); + + assertNull(CacheServiceLoader.getService()); + } +} diff --git a/core/cache/src/test/resources/log4j.xml b/core/cache/src/test/resources/log4j.xml index 597b6690e21..7090720d48c 100644 --- a/core/cache/src/test/resources/log4j.xml +++ b/core/cache/src/test/resources/log4j.xml @@ -24,7 +24,7 @@ - + diff --git a/core/graph/src/main/java/uk/gov/gchq/gaffer/graph/Graph.java b/core/graph/src/main/java/uk/gov/gchq/gaffer/graph/Graph.java index 122ac8fc43c..13d56e5a674 100644 --- a/core/graph/src/main/java/uk/gov/gchq/gaffer/graph/Graph.java +++ b/core/graph/src/main/java/uk/gov/gchq/gaffer/graph/Graph.java @@ -23,6 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import uk.gov.gchq.gaffer.cache.Cache; import uk.gov.gchq.gaffer.commonutil.CloseableUtil; import uk.gov.gchq.gaffer.commonutil.StreamUtil; import uk.gov.gchq.gaffer.commonutil.pair.Pair; @@ -491,6 +492,9 @@ public GraphLibrary getGraphLibrary() { return store.getGraphLibrary(); } + public List> getCaches() { + return store.getCaches(); + } @FunctionalInterface private interface StoreExecuter { diff --git a/core/graph/src/test/java/uk/gov/gchq/gaffer/integration/operation/named/cache/NamedOperationCacheIT.java b/core/graph/src/test/java/uk/gov/gchq/gaffer/integration/operation/named/cache/NamedOperationCacheIT.java index 20b514a15af..ae78f8c4b06 100644 --- a/core/graph/src/test/java/uk/gov/gchq/gaffer/integration/operation/named/cache/NamedOperationCacheIT.java +++ b/core/graph/src/test/java/uk/gov/gchq/gaffer/integration/operation/named/cache/NamedOperationCacheIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import uk.gov.gchq.gaffer.cache.CacheServiceLoader; import uk.gov.gchq.gaffer.cache.exception.CacheOperationException; import uk.gov.gchq.gaffer.cache.impl.HashMapCacheService; -import uk.gov.gchq.gaffer.cache.util.CacheProperties; import uk.gov.gchq.gaffer.named.operation.AddNamedOperation; import uk.gov.gchq.gaffer.named.operation.DeleteNamedOperation; import uk.gov.gchq.gaffer.named.operation.GetAllNamedOperations; @@ -43,7 +42,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Properties; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -53,7 +51,6 @@ public class NamedOperationCacheIT { private static final String CACHE_NAME = "NamedOperation"; public static final String SUFFIX = "suffix"; - private final Properties cacheProps = new Properties(); private final Store store = mock(Store.class); private final String adminAuth = "admin auth"; private final StoreProperties properties = new StoreProperties(); @@ -81,15 +78,14 @@ public class NamedOperationCacheIT { @BeforeEach public void before() throws CacheOperationException { - cacheProps.clear(); properties.setAdminAuth(adminAuth); given(store.getProperties()).willReturn(properties); } @AfterEach public void after() throws CacheOperationException { - CacheServiceLoader.getService().clearCache(CACHE_NAME); - CacheServiceLoader.getService().clearCache(NamedOperationCache.getCacheNameFrom(SUFFIX)); + CacheServiceLoader.getDefaultService().clearCache(CACHE_NAME); + CacheServiceLoader.getDefaultService().clearCache(NamedOperationCache.getCacheNameFrom(SUFFIX)); } @Test @@ -99,9 +95,8 @@ public void shouldWorkUsingHashMapServiceClass() throws OperationException, Cach } private void reInitialiseCacheService(final Class clazz) throws CacheOperationException { - cacheProps.setProperty(CacheProperties.CACHE_SERVICE_CLASS, clazz.getCanonicalName()); - CacheServiceLoader.initialise(cacheProps); - CacheServiceLoader.getService().clearCache(CACHE_NAME); + CacheServiceLoader.initialise(clazz.getCanonicalName()); + CacheServiceLoader.getDefaultService().clearCache(CACHE_NAME); } private void runTests() throws OperationException, CacheOperationException { diff --git a/core/operation/src/main/java/uk/gov/gchq/gaffer/jobtracker/JobTracker.java b/core/operation/src/main/java/uk/gov/gchq/gaffer/jobtracker/JobTracker.java index a9874b9cf37..d1ad77afa31 100644 --- a/core/operation/src/main/java/uk/gov/gchq/gaffer/jobtracker/JobTracker.java +++ b/core/operation/src/main/java/uk/gov/gchq/gaffer/jobtracker/JobTracker.java @@ -36,9 +36,9 @@ * details of jobs submitted to the graph. */ public class JobTracker extends Cache { - private static final Logger LOGGER = LoggerFactory.getLogger(JobTracker.class); private static final String CACHE_SERVICE_NAME_PREFIX = "JobTracker"; + public static final String JOB_TRACKER_CACHE_SERVICE_NAME = "JobTracker"; /** * Executor to allow queuing up async operations on the cache. @@ -50,7 +50,7 @@ public class JobTracker extends Cache { private final ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>()); public JobTracker(final String suffixJobTrackerCacheName) { - super(getCacheNameFrom(suffixJobTrackerCacheName)); + super(getCacheNameFrom(suffixJobTrackerCacheName), JOB_TRACKER_CACHE_SERVICE_NAME); } public static String getCacheNameFrom(final String suffixJobTrackerCacheName) { diff --git a/core/operation/src/test/java/uk/gov/gchq/gaffer/jobtracker/JobTrackerBrokenCacheTest.java b/core/operation/src/test/java/uk/gov/gchq/gaffer/jobtracker/JobTrackerBrokenCacheTest.java index c96c228f42b..55891d98bd0 100644 --- a/core/operation/src/test/java/uk/gov/gchq/gaffer/jobtracker/JobTrackerBrokenCacheTest.java +++ b/core/operation/src/test/java/uk/gov/gchq/gaffer/jobtracker/JobTrackerBrokenCacheTest.java @@ -29,12 +29,15 @@ import uk.gov.gchq.gaffer.user.User; import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThatCode; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.doThrow; +import static uk.gov.gchq.gaffer.jobtracker.JobTracker.JOB_TRACKER_CACHE_SERVICE_NAME; public class JobTrackerBrokenCacheTest { @BeforeAll @@ -44,9 +47,10 @@ public static void setUp() throws Exception { ICacheService mockICacheService = Mockito.spy(ICacheService.class); given(mockICacheService.getCache(any())).willReturn(mockICache); - Field field = CacheServiceLoader.class.getDeclaredField("service"); + Field field = CacheServiceLoader.class.getDeclaredField("SERVICES"); field.setAccessible(true); - field.set(null, mockICacheService); + Map mockCacheServices = (Map) field.get(new HashMap<>()); + mockCacheServices.put(JOB_TRACKER_CACHE_SERVICE_NAME, mockICacheService); } @Test diff --git a/core/store/src/main/java/uk/gov/gchq/gaffer/store/Store.java b/core/store/src/main/java/uk/gov/gchq/gaffer/store/Store.java index 430ef2f61d8..80530499202 100644 --- a/core/store/src/main/java/uk/gov/gchq/gaffer/store/Store.java +++ b/core/store/src/main/java/uk/gov/gchq/gaffer/store/Store.java @@ -20,6 +20,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import uk.gov.gchq.gaffer.cache.Cache; import uk.gov.gchq.gaffer.cache.CacheServiceLoader; import uk.gov.gchq.gaffer.commonutil.CloseableUtil; import uk.gov.gchq.gaffer.commonutil.ExecutorService; @@ -149,6 +150,8 @@ import uk.gov.gchq.gaffer.store.operation.handler.named.GetAllNamedOperationsHandler; import uk.gov.gchq.gaffer.store.operation.handler.named.GetAllNamedViewsHandler; import uk.gov.gchq.gaffer.store.operation.handler.named.NamedOperationHandler; +import uk.gov.gchq.gaffer.store.operation.handler.named.cache.NamedOperationCache; +import uk.gov.gchq.gaffer.store.operation.handler.named.cache.NamedViewCache; import uk.gov.gchq.gaffer.store.operation.handler.output.ToArrayHandler; import uk.gov.gchq.gaffer.store.operation.handler.output.ToCsvHandler; import uk.gov.gchq.gaffer.store.operation.handler.output.ToEntitySeedsHandler; @@ -183,6 +186,10 @@ import static java.util.Collections.unmodifiableList; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; +import static uk.gov.gchq.gaffer.cache.CacheServiceLoader.DEFAULT_SERVICE_NAME; +import static uk.gov.gchq.gaffer.jobtracker.JobTracker.JOB_TRACKER_CACHE_SERVICE_NAME; +import static uk.gov.gchq.gaffer.store.operation.handler.named.cache.NamedOperationCache.NAMED_OPERATION_CACHE_SERVICE_NAME; +import static uk.gov.gchq.gaffer.store.operation.handler.named.cache.NamedViewCache.NAMED_VIEW_CACHE_SERVICE_NAME; /** * A {@code Store} backs a Graph and is responsible for storing the {@link @@ -224,7 +231,8 @@ public abstract class Store { private GraphLibrary library; - private JobTracker jobTracker; + JobTracker jobTracker; + private List> caches; private String graphId; private boolean jobsRescheduled = false; @@ -283,7 +291,7 @@ public void initialise(final String graphId, final Schema schema, final StorePro updateJsonSerialiser(); startCacheServiceLoader(properties); - this.jobTracker = createJobTracker(); + populateCaches(); addOpHandlers(); optimiseSchema(); @@ -545,6 +553,10 @@ public JobTracker getJobTracker() { return jobTracker; } + public List> getCaches() { + return unmodifiableList(caches); + } + /** * @param operationClass the operation class to check * @return true if the provided operation is supported. @@ -802,11 +814,19 @@ protected void validateSchema(final ValidationResult validationResult, final Ser } } - protected JobTracker createJobTracker() { + protected void populateCaches() { + caches = new ArrayList<>(); if (properties.getJobTrackerEnabled()) { - return new JobTracker(getProperties().getCacheServiceJobTrackerSuffix(graphId)); + jobTracker = new JobTracker(getProperties().getCacheServiceJobTrackerSuffix(graphId)); + caches.add(jobTracker); + } + if (CacheServiceLoader.isDefaultEnabled() || + (CacheServiceLoader.isEnabled(NAMED_OPERATION_CACHE_SERVICE_NAME) && + CacheServiceLoader.isEnabled(NAMED_VIEW_CACHE_SERVICE_NAME)) + ) { + caches.add(new NamedOperationCache(getProperties().getCacheServiceNamedOperationSuffix(graphId))); + caches.add(new NamedViewCache(getProperties().getCacheServiceNamedViewSuffix(graphId))); } - return null; } protected SchemaOptimiser createSchemaOptimiser() { @@ -1017,7 +1037,10 @@ private void addCoreOpHandlers() { addOperationHandler(ToStream.class, new ToStreamHandler<>()); addOperationHandler(ToVertices.class, new ToVerticesHandler()); - if (nonNull(CacheServiceLoader.getService())) { + if (CacheServiceLoader.isDefaultEnabled() || + (CacheServiceLoader.isEnabled(NAMED_OPERATION_CACHE_SERVICE_NAME) && + CacheServiceLoader.isEnabled(NAMED_VIEW_CACHE_SERVICE_NAME)) + ) { // Named operation addOperationHandler(NamedOperation.class, new NamedOperationHandler()); final String suffixNamedOperationCacheName = properties.getCacheServiceNamedOperationSuffix(graphId); @@ -1096,6 +1119,27 @@ private void addConfiguredOperationHandlers() { } protected void startCacheServiceLoader(final StoreProperties properties) { - CacheServiceLoader.initialise(properties.getProperties()); + final String jobTrackerCacheClass = properties.getJobTrackerCacheServiceClass(); + final String namedViewCacheClass = properties.getNamedViewCacheServiceClass(); + final String namedOperationCacheClass = properties.getNamedOperationCacheServiceClass(); + final String defaultCacheClass = properties.getDefaultCacheServiceClass(); + final boolean jobTrackerEnabled = properties.getJobTrackerEnabled(); + final boolean defaultServiceRequired = (jobTrackerEnabled && jobTrackerCacheClass == null) | + (namedViewCacheClass == null) | (namedOperationCacheClass == null); + + if (jobTrackerEnabled && jobTrackerCacheClass != null) { + CacheServiceLoader.initialise(JOB_TRACKER_CACHE_SERVICE_NAME, jobTrackerCacheClass, properties.getProperties()); + } + if (namedViewCacheClass != null) { + CacheServiceLoader.initialise(NAMED_VIEW_CACHE_SERVICE_NAME, namedViewCacheClass, properties.getProperties()); + } + if (namedOperationCacheClass != null) { + CacheServiceLoader.initialise(NAMED_OPERATION_CACHE_SERVICE_NAME, namedOperationCacheClass, properties.getProperties()); + } + if (defaultServiceRequired && defaultCacheClass != null) { + CacheServiceLoader.initialise(DEFAULT_SERVICE_NAME, properties.getDefaultCacheServiceClass(), properties.getProperties()); + } else if (defaultServiceRequired) { + LOGGER.info("Store Properties did not include a default cache class, caches not fully initialised"); + } } } diff --git a/core/store/src/main/java/uk/gov/gchq/gaffer/store/StoreProperties.java b/core/store/src/main/java/uk/gov/gchq/gaffer/store/StoreProperties.java index e0c3cd7ada2..feff41c0837 100644 --- a/core/store/src/main/java/uk/gov/gchq/gaffer/store/StoreProperties.java +++ b/core/store/src/main/java/uk/gov/gchq/gaffer/store/StoreProperties.java @@ -26,7 +26,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import uk.gov.gchq.gaffer.cache.util.CacheProperties; import uk.gov.gchq.gaffer.commonutil.DebugUtil; import uk.gov.gchq.gaffer.commonutil.StreamUtil; import uk.gov.gchq.gaffer.commonutil.ToStringBuilder; @@ -49,6 +48,15 @@ import static java.lang.Boolean.parseBoolean; import static java.util.Objects.nonNull; +import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_CLASS; +import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_DEFAULT_CLASS; +import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX; +import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_JOB_TRACKER_CLASS; +import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_JOB_TRACKER_SUFFIX; +import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_NAMED_OPERATION_CLASS; +import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_NAMED_OPERATION_SUFFIX; +import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_NAMED_VIEW_CLASS; +import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_NAMED_VIEW_SUFFIX; import static uk.gov.gchq.gaffer.store.operation.handler.named.AddNamedOperationHandler.DEFAULT_IS_NESTED_NAMED_OPERATIONS_ALLOWED; /** @@ -79,22 +87,6 @@ public class StoreProperties implements Cloneable { public static final String ADMIN_AUTH = "gaffer.store.admin.auth"; - /** - * This is used to set the cache implementation for all caches - * e.g. gaffer.cache.service.class="uk.gov.gchq.gaffer.cache.impl.HashMapCacheService" - */ - public static final String CACHE_SERVICE_CLASS = CacheProperties.CACHE_SERVICE_CLASS; - - /** - * These are used to set the suffix for all caches or per cache - * CASE INSENSITIVE - * e.g. gaffer.cache.service.default.suffix="v2" - */ - public static final String CACHE_SERVICE_DEFAULT_SUFFIX = "gaffer.cache.service.default.suffix"; - public static final String CACHE_SERVICE_NAMED_OPERATION_SUFFIX = "gaffer.cache.service.named.operation.suffix"; - public static final String CACHE_SERVICE_JOB_TRACKER_SUFFIX = "gaffer.cache.service.job.tracker.suffix"; - public static final String CACHE_SERVICE_NAMED_VIEW_SUFFIX = "gaffer.cache.service.named.view.suffix"; - /** * CSV of extra packages to be included in the reflection scanning. */ @@ -352,7 +344,7 @@ public void setSchemaClass(final String schemaClass) { } public void setSchemaClass(final Class schemaClass) { - set(SCHEMA_CLASS, schemaClass.getName()); + setSchemaClass(schemaClass.getName()); } public String getStorePropertiesClassName() { @@ -457,16 +449,55 @@ public void setAdminAuth(final String adminAuth) { set(ADMIN_AUTH, adminAuth); } + public String getDefaultCacheServiceClass() { + final String defaultCacheClass = get(CACHE_SERVICE_DEFAULT_CLASS); + // Fallback to old CACHE_SERVICE_CLASS property if CACHE_SERVICE_DEFAULT_CLASS is missing + return (defaultCacheClass == null ? get(CACHE_SERVICE_CLASS) : defaultCacheClass); + } + + public void setDefaultCacheServiceClass(final String cacheServiceClassString) { + set(CACHE_SERVICE_DEFAULT_CLASS, cacheServiceClassString); + } + + public String getJobTrackerCacheServiceClass() { + return get(CACHE_SERVICE_JOB_TRACKER_CLASS); + } + + public void setJobTrackerCacheServiceClass(final String cacheServiceClassString) { + set(CACHE_SERVICE_JOB_TRACKER_CLASS, cacheServiceClassString); + } + + public String getNamedViewCacheServiceClass() { + return get(CACHE_SERVICE_NAMED_VIEW_CLASS); + } + + public void setNamedViewCacheServiceClass(final String cacheServiceClassString) { + set(CACHE_SERVICE_NAMED_VIEW_CLASS, cacheServiceClassString); + } + + public String getNamedOperationCacheServiceClass() { + return get(CACHE_SERVICE_NAMED_OPERATION_CLASS); + } + + public void setNamedOperationCacheServiceClass(final String cacheServiceClassString) { + set(CACHE_SERVICE_NAMED_OPERATION_CLASS, cacheServiceClassString); + } + + @Deprecated public void setCacheServiceClass(final String cacheServiceClassString) { set(CACHE_SERVICE_CLASS, cacheServiceClassString); + setDefaultCacheServiceClass(cacheServiceClassString); } + @Deprecated public String getCacheServiceClass() { return getCacheServiceClass(null); } + @Deprecated public String getCacheServiceClass(final String defaultValue) { - return get(CACHE_SERVICE_CLASS, defaultValue); + final String cacheServiceClass = getDefaultCacheServiceClass(); + return (cacheServiceClass != null) ? cacheServiceClass : get(CACHE_SERVICE_CLASS, defaultValue); } public void setCacheServiceNameSuffix(final String suffix) { diff --git a/core/store/src/main/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedOperationCache.java b/core/store/src/main/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedOperationCache.java index 42e16d1a520..0871afb3b4c 100644 --- a/core/store/src/main/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedOperationCache.java +++ b/core/store/src/main/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedOperationCache.java @@ -39,9 +39,10 @@ public class NamedOperationCache extends Cache { private static final Logger LOGGER = LoggerFactory.getLogger(NamedOperationCache.class); public static final String CACHE_SERVICE_NAME_PREFIX = "NamedOperation"; public static final String NAMED_OPERATION_CACHE_WAS_MADE_WITH_NULL_OR_EMPTY_SUFFIX = "NamedOperation Cache was made with Null or Empty suffix, This is very likely a mistake. GraphId or a supplied suffix is normal"; + public static final String NAMED_OPERATION_CACHE_SERVICE_NAME = "NamedOperation"; public NamedOperationCache(final String suffixNamedOperationCacheName) { - super(getCacheNameFrom(suffixNamedOperationCacheName)); + super(getCacheNameFrom(suffixNamedOperationCacheName), NAMED_OPERATION_CACHE_SERVICE_NAME); if (Strings.isNullOrEmpty(suffixNamedOperationCacheName)) { LOGGER.error(NAMED_OPERATION_CACHE_WAS_MADE_WITH_NULL_OR_EMPTY_SUFFIX); } diff --git a/core/store/src/main/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCache.java b/core/store/src/main/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCache.java index e5a9ef8febc..7700bedc766 100644 --- a/core/store/src/main/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCache.java +++ b/core/store/src/main/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCache.java @@ -32,11 +32,11 @@ * the {@link uk.gov.gchq.gaffer.data.elementdefinition.view.NamedView}s for a Gaffer graph. */ public class NamedViewCache extends Cache { - public static final String CACHE_SERVICE_NAME_PREFIX = "NamedView"; + public static final String NAMED_VIEW_CACHE_SERVICE_NAME = "NamedView"; public NamedViewCache(final String suffixNamedViewCacheName) { - super(getCacheNameFrom(suffixNamedViewCacheName)); + super(getCacheNameFrom(suffixNamedViewCacheName), NAMED_VIEW_CACHE_SERVICE_NAME); } public static String getCacheNameFrom(final String suffixNamedViewCacheName) { diff --git a/core/store/src/test/java/uk/gov/gchq/gaffer/store/StorePropertiesTest.java b/core/store/src/test/java/uk/gov/gchq/gaffer/store/StorePropertiesTest.java index e2e8fe3057a..0bf87b80dbd 100644 --- a/core/store/src/test/java/uk/gov/gchq/gaffer/store/StorePropertiesTest.java +++ b/core/store/src/test/java/uk/gov/gchq/gaffer/store/StorePropertiesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 Crown Copyright + * Copyright 2016-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,20 +17,30 @@ package uk.gov.gchq.gaffer.store; import com.fasterxml.jackson.databind.Module; -import com.google.common.collect.Sets; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import uk.gov.gchq.gaffer.commonutil.StreamUtil; +import uk.gov.gchq.gaffer.data.elementdefinition.exception.SchemaException; import uk.gov.gchq.gaffer.jsonserialisation.JSONSerialiserModules; +import uk.gov.gchq.gaffer.store.schema.Schema; import uk.gov.gchq.koryphe.util.ReflectionUtil; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashSet; import java.util.List; +import java.util.Properties; import java.util.Set; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static uk.gov.gchq.gaffer.store.StoreProperties.loadStoreProperties; public class StorePropertiesTest { @@ -43,165 +53,471 @@ public void cleanUp() { @Test public void shouldMergeProperties() { // Given - final StoreProperties props1 = createStoreProperties(); - final StoreProperties props2 = StoreProperties.loadStoreProperties(StreamUtil.openStream(getClass(), "store2.properties")); + final StoreProperties props1 = loadStoreProperties("store.properties"); + final StoreProperties props2 = loadStoreProperties("store2.properties"); // When props1.merge(props2); // Then - assertEquals("value1", props1.get("key1")); - assertEquals("value2", props1.get("key2")); - assertEquals("value2", props1.get("testKey")); + assertThat(props1.get("key1")).isEqualTo("value1"); + assertThat(props1.get("key2")).isEqualTo("value2"); + assertThat(props1.get("testKey")).isEqualTo("value2"); } @Test public void shouldRemovePropertyWhenPropertyValueIsNull() { // Given - final StoreProperties props = createStoreProperties(); + final StoreProperties props = new StoreProperties(); // When props.set("testKey", null); // Then - assertNull(props.get("testKey")); + assertThat(props.get("testKey")).isNull(); } @Test public void shouldGetProperty() { // Given - final StoreProperties props = createStoreProperties(); + final StoreProperties props = loadStoreProperties("store.properties"); // When String value = props.get("key1"); // Then - assertEquals("value1", value); + assertThat(value).isEqualTo("value1"); } @Test public void shouldSetAndGetProperty() { // Given - final StoreProperties props = createStoreProperties(); + final StoreProperties props = new StoreProperties(); // When props.set("key2", "value2"); String value = props.get("key2"); // Then - assertEquals("value2", value); + assertThat(value).isEqualTo("value2"); } @Test public void shouldGetPropertyWithDefaultValue() { // Given - final StoreProperties props = createStoreProperties(); + final StoreProperties props = loadStoreProperties("store.properties"); // When String value = props.get("key1", "property not found"); // Then - assertEquals("value1", value); + assertThat(value).isEqualTo("value1"); } @Test public void shouldGetUnknownProperty() { // Given - final StoreProperties props = createStoreProperties(); + final StoreProperties props = new StoreProperties(); // When String value = props.get("a key that does not exist"); // Then - assertNull(value); + assertThat(value).isNull(); } @Test public void shouldAddOperationDeclarationPathsWhenNullExisting() { // Given - final StoreProperties props = createStoreProperties(); - assertNull(props.getOperationDeclarationPaths()); + final StoreProperties props = new StoreProperties(); + assertThat(props.getOperationDeclarationPaths()).isNull(); // When props.addOperationDeclarationPaths("1", "2"); // Then - assertEquals("1,2", props.getOperationDeclarationPaths()); + assertThat(props.getOperationDeclarationPaths()).isEqualTo("1,2"); } @Test public void shouldAddOperationDeclarationPathsWhenExisting() { // Given - final StoreProperties props = createStoreProperties(); + final StoreProperties props = new StoreProperties(); props.setOperationDeclarationPaths("1"); // When props.addOperationDeclarationPaths("2", "3"); // Then - assertEquals("1,2,3", props.getOperationDeclarationPaths()); + assertThat(props.getOperationDeclarationPaths()).isEqualTo("1,2,3"); } @Test public void shouldAddReflectionPackagesToKorypheReflectionUtil() { // Given - final StoreProperties props = createStoreProperties(); + final StoreProperties props = new StoreProperties(); // When props.setReflectionPackages("package1,package2"); // Then - assertEquals("package1,package2", props.getReflectionPackages()); - final Set expectedPackages = Sets.newHashSet(ReflectionUtil.DEFAULT_PACKAGES); + assertThat(props.getReflectionPackages()).isEqualTo("package1,package2"); + final Set expectedPackages = new HashSet<>(ReflectionUtil.DEFAULT_PACKAGES); expectedPackages.add("package1"); expectedPackages.add("package2"); - assertEquals(expectedPackages, ReflectionUtil.getReflectionPackages()); + assertThat(ReflectionUtil.getReflectionPackages()).isEqualTo(expectedPackages); } @Test public void shouldGetUnknownPropertyWithDefaultValue() { // Given - final StoreProperties props = createStoreProperties(); + final StoreProperties props = new StoreProperties(); // When String value = props.get("a key that does not exist", "property not found"); // Then - assertEquals("property not found", value); - } - - private StoreProperties createStoreProperties() { - return StoreProperties.loadStoreProperties(StreamUtil.storeProps(getClass())); + assertThat(value).isEqualTo("property not found"); } @Test public void shouldSetJsonSerialiserModules() { // Given - final StoreProperties props = createStoreProperties(); - final Set> modules = Sets.newHashSet( - TestCustomJsonModules1.class, - TestCustomJsonModules2.class - ); + final StoreProperties props = new StoreProperties(); + final Set> modules = new HashSet<>(); + modules.add(TestCustomJsonModules1.class); + modules.add(TestCustomJsonModules2.class); // When props.setJsonSerialiserModules(modules); // Then final String expected = TestCustomJsonModules1.class.getName() + "," + TestCustomJsonModules2.class.getName(); - assertEquals(expected, props.getJsonSerialiserModules()); + assertThat(props.getJsonSerialiserModules()).isEqualTo(expected); } @Test public void shouldGetAndSetAdminAuth() { // Given final String adminAuth = "admin auth"; - final StoreProperties props = createStoreProperties(); + final StoreProperties props = new StoreProperties(); // When props.setAdminAuth(adminAuth); // Then - assertEquals(adminAuth, props.getAdminAuth()); + assertThat(props.getAdminAuth()).isEqualTo(adminAuth); + } + + @Test + public void shouldGetAndSetStoreClass() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.getStoreClass()).isNull(); + + // Given / When + props.setStoreClass(Store.class); + // Then + assertThat(props.getStoreClass()).isEqualTo(Store.class.getName()); + } + + @Test + public void shouldGetAndSetJobTrackerEnabled() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.getJobTrackerEnabled()).isFalse(); + + // Given / When + props.setJobTrackerEnabled(true); + // Then + assertThat(props.getJobTrackerEnabled()).isTrue(); + } + + @Test + public void shouldGetAndSetSchemaClass() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.getSchemaClass()).isEqualTo(Schema.class); + + // Given + final String invalidSchemaClass = "unchecked.invalid.Schema.class"; + // When + props.setSchemaClass(invalidSchemaClass); + // Then + assertThat(props.getSchemaClassName()).isEqualTo(invalidSchemaClass); + + // Given / When + props.setSchemaClass(Schema.class); + // Then + assertThat(props.getSchemaClass()).isEqualTo(Schema.class); + } + + @Test + public void shouldThrowExceptionForInvalidStorePropertiesClass() { + // Given + final StoreProperties props = new StoreProperties(); + final String invalidPropsClass = "invalid.props.class"; + // When + props.setStorePropertiesClassName(invalidPropsClass); + // Then + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(props::getStorePropertiesClass) + .withMessage(String.format("Store properties class was not found: %s", invalidPropsClass)); + } + + @Test + public void shouldThrowExceptionGettingInvalidSchemaClass() { + // Given + final StoreProperties props = new StoreProperties(); + final String invalidSchemaClass = "invalid.Schema.class"; + // When + props.setSchemaClass(invalidSchemaClass); + // Then + assertThatExceptionOfType(SchemaException.class) + .isThrownBy(props::getSchemaClass) + .withMessage(String.format("Schema class was not found: %s", invalidSchemaClass)); + } + + @Test + public void shouldGetAndSetJsonSerialiserClass() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.getJsonSerialiserClass()).isNull(); + + // Given + String invalidClass = "invalid.class"; + // When + props.setJsonSerialiserClass(invalidClass); + // Then + assertThat(props.getJsonSerialiserClass()).isEqualTo(invalidClass); + } + + @Test + public void shouldGetAndSetStrictJson() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.getStrictJson()).isNull(); + + // Given / When + props.setStrictJson(true); + // Then + assertThat(props.getStrictJson()).isTrue(); + + // Given / When + props.setStrictJson(null); + // Then + assertThat(props.getStrictJson()).isNull(); + } + + @Test + public void shouldGetAndSetDefaultCacheService() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.getDefaultCacheServiceClass()).isNull(); + + // Given + final String cacheServiceClassString = "example.cache.class"; + // When + props.setDefaultCacheServiceClass(cacheServiceClassString); + // Then + assertThat(props.getDefaultCacheServiceClass()).isEqualTo(cacheServiceClassString); + + // Given / When + final StoreProperties props2 = loadStoreProperties("legacyStore.properties"); + // Then + assertThat(props2.getDefaultCacheServiceClass()).isNotNull(); + } + + @Test + @Deprecated + public void shouldGetAndSetCacheServiceWithDeprecatedMethods() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.getCacheServiceClass()).isNull(); + + // Given / When + final StoreProperties props2 = loadStoreProperties("legacyStore.properties"); + // Then + assertThat(props2.getCacheServiceClass()).isNotNull(); + + // Given + final String cacheServiceClassString = "example.cache.class"; + // When + props.setCacheServiceClass(cacheServiceClassString); + // Then + assertThat(props.getCacheServiceClass()).isEqualTo(cacheServiceClassString); + assertThat(props.getDefaultCacheServiceClass()).isEqualTo(cacheServiceClassString); + } + + @Test + public void shouldGetAndSetSpecificCacheServices() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.getJobTrackerCacheServiceClass()).isNull(); + assertThat(props.getNamedViewCacheServiceClass()).isNull(); + assertThat(props.getNamedOperationCacheServiceClass()).isNull(); + + // Given + final String cacheServiceClassString = "example.cache.class"; + // When + props.setJobTrackerCacheServiceClass(cacheServiceClassString); + props.setNamedViewCacheServiceClass(cacheServiceClassString); + props.setNamedOperationCacheServiceClass(cacheServiceClassString); + // Then + assertThat(props.getJobTrackerCacheServiceClass()).isEqualTo(cacheServiceClassString); + assertThat(props.getNamedViewCacheServiceClass()).isEqualTo(cacheServiceClassString); + assertThat(props.getNamedOperationCacheServiceClass()).isEqualTo(cacheServiceClassString); + } + + @Test + public void shouldGetAndSetAllowNestedNamedOperation() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.isNestedNamedOperationAllow()).isFalse(); + assertThat(props.isNestedNamedOperationAllow(false)).isFalse(); + assertThat(props.isNestedNamedOperationAllow(true)).isTrue(); + + // Given / When + props.setNestedNamedOperationAllow(true); + // Then + assertThat(props.isNestedNamedOperationAllow()).isTrue(); + assertThat(props.isNestedNamedOperationAllow(false)).isTrue(); + assertThat(props.isNestedNamedOperationAllow(true)).isTrue(); + } + + @Test + public void shouldGetAndSetCacheSuffixes() { + // Given / When + final StoreProperties props = new StoreProperties(); + // Then + assertThat(props.getCacheServiceDefaultSuffix(null)).isNull(); + assertThat(props.getCacheServiceJobTrackerSuffix(null)).isNull(); + assertThat(props.getCacheServiceNamedViewSuffix(null)).isNull(); + assertThat(props.getCacheServiceNamedOperationSuffix(null)).isNull(); + + // Given + final String suffix = "mySuffix"; + // When + props.setCacheServiceNameSuffix(suffix); + // Then + assertThat(props.getCacheServiceDefaultSuffix(null)).isEqualTo(suffix); + + // Given / When + final StoreProperties props2 = loadStoreProperties("suffixes.properties"); + // Then + assertThat(props2.getCacheServiceDefaultSuffix(null)).isEqualTo("default"); + assertThat(props2.getCacheServiceJobTrackerSuffix(null)).isEqualTo("jt"); + assertThat(props2.getCacheServiceNamedViewSuffix(null)).isEqualTo("nv"); + assertThat(props2.getCacheServiceNamedOperationSuffix(null)).isEqualTo("no"); + } + + @Test + public void shouldConstructStorePropertiesFromPath(@TempDir Path tempDir) throws IOException { + // Given + Path propsPath = tempDir.resolve("tmp.properties"); + Files.write(propsPath, "key=value".getBytes()); + // When + StoreProperties props = new StoreProperties(propsPath); + // Then + assertThat(props.get("key")).isEqualTo("value"); + } + + @Test + public void shouldThrowExceptionConstructingStorePropertiesFromMissingPath(@TempDir Path tempDir) { + // Given + Path propsPath = tempDir.resolve("missing"); + // When / Then + assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> new StoreProperties(propsPath)) + .withMessageContaining("java.nio.file.NoSuchFileException") + .withMessageContaining("/missing"); + } + + @Test + public void shouldNotThrowExceptionConstructingStorePropertiesFromNullPath() { + // Given + Path propsPath = null; + // When / Then + assertThatCode(() -> new StoreProperties(propsPath)).doesNotThrowAnyException(); + } + + @Test + public void shouldConstructStorePropertiesFromProperties() { + // Given + final Properties props = new Properties(); + // When / Then + assertThatCode(() -> new StoreProperties(props)).doesNotThrowAnyException(); + } + + @Test + public void shouldReturnStorePropertiesFromPropertiesAndClass() { + // Given + final Properties props = new Properties(); + // When / Then + assertThatCode(() -> loadStoreProperties(props, StoreProperties.class)).doesNotThrowAnyException(); + } + + @Test + public void shouldThrowExceptionWhenTryingToReturnStorePropertiesFromPropertiesWithInvalidClass() { + // Given + final Properties props = new Properties(); + final String className = "invalid.missing.class"; + props.setProperty(StoreProperties.STORE_PROPERTIES_CLASS, className); + // When / Then + assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> loadStoreProperties(props)) + .withMessage(String.format("Failed to create store properties file : %s", className)); + } + + @Test + public void shouldReturnStorePropertiesFromPathAndClass(@TempDir Path tempDir) throws IOException { + // Given + Path propsPath = tempDir.resolve("tmp.properties"); + Files.write(propsPath, "key=value".getBytes()); + // When + StoreProperties props = loadStoreProperties(propsPath, StoreProperties.class); + // Then + assertThat(props.get("key")).isEqualTo("value"); + assertThat(props.getClass()).isEqualTo(StoreProperties.class); + } + + @Test + public void shouldReturnStorePropertiesFromPathStringAndClass(@TempDir Path tempDir) throws IOException { + // Given + Path propsPath = tempDir.resolve("tmp.properties"); + Files.write(propsPath, "key=value".getBytes()); + String propsPathString = propsPath.toString(); + // When + StoreProperties props = loadStoreProperties(propsPathString, StoreProperties.class); + // Then + assertThat(props.get("key")).isEqualTo("value"); + assertThat(props.getClass()).isEqualTo(StoreProperties.class); + } + + @Test + public void shouldReturnStorePropertiesFromInputStreamAndClass() { + // Given + InputStream inputStream = StreamUtil.openStream(StorePropertiesTest.class, "store.properties"); + // When + StoreProperties props = loadStoreProperties(inputStream, StoreProperties.class); + // Then + assertThat(props.get("key1")).isEqualTo("value1"); + assertThat(props.getClass()).isEqualTo(StoreProperties.class); + } + + @Test + public void shouldReturnStorePropertiesFromNullInputStream() { + // Given + InputStream inputStream = null; + // When / Then + assertThatCode(() -> loadStoreProperties(inputStream)).doesNotThrowAnyException(); } public static final class TestCustomJsonModules1 implements JSONSerialiserModules { diff --git a/core/store/src/test/java/uk/gov/gchq/gaffer/store/StoreTest.java b/core/store/src/test/java/uk/gov/gchq/gaffer/store/StoreTest.java index dfdcdd9ca4e..17440a0b65b 100644 --- a/core/store/src/test/java/uk/gov/gchq/gaffer/store/StoreTest.java +++ b/core/store/src/test/java/uk/gov/gchq/gaffer/store/StoreTest.java @@ -33,7 +33,6 @@ import uk.gov.gchq.gaffer.cache.ICacheService; import uk.gov.gchq.gaffer.cache.exception.CacheOperationException; import uk.gov.gchq.gaffer.cache.impl.HashMapCacheService; -import uk.gov.gchq.gaffer.cache.util.CacheProperties; import uk.gov.gchq.gaffer.commonutil.TestGroups; import uk.gov.gchq.gaffer.commonutil.TestPropertyNames; import uk.gov.gchq.gaffer.data.element.Element; @@ -141,9 +140,9 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Properties; import java.util.Set; import java.util.concurrent.RunnableScheduledFuture; import java.util.concurrent.ScheduledExecutorService; @@ -167,6 +166,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static uk.gov.gchq.gaffer.jobtracker.JobTracker.JOB_TRACKER_CACHE_SERVICE_NAME; import static uk.gov.gchq.gaffer.store.StoreTrait.INGEST_AGGREGATION; import static uk.gov.gchq.gaffer.store.StoreTrait.ORDERED; import static uk.gov.gchq.gaffer.store.StoreTrait.PRE_AGGREGATION_FILTERING; @@ -203,6 +203,7 @@ public class StoreTest { @BeforeEach public void setup() { + CacheServiceLoader.shutdown(); System.clearProperty(JSONSerialiser.JSON_SERIALISER_CLASS_KEY); System.clearProperty(JSONSerialiser.JSON_SERIALISER_MODULES); JSONSerialiser.update(); @@ -259,9 +260,10 @@ public void shouldExecuteOperationWhenJobTrackerCacheIsBroken(@Mock final StoreP ICacheService mockICacheService = Mockito.spy(ICacheService.class); given(mockICacheService.getCache(any())).willReturn(mockICache); - Field field = CacheServiceLoader.class.getDeclaredField("service"); + Field field = CacheServiceLoader.class.getDeclaredField("SERVICES"); field.setAccessible(true); - field.set(null, mockICacheService); + java.util.Map mockCacheServices = (java.util.Map) field.get(new HashMap<>()); + mockCacheServices.put(JOB_TRACKER_CACHE_SERVICE_NAME, mockICacheService); final AddElements addElements = new AddElements(); final StoreImpl3 store = new StoreImpl3(); @@ -276,6 +278,35 @@ public void shouldExecuteOperationWhenJobTrackerCacheIsBroken(@Mock final StoreP verify(mockICache, Mockito.atLeast(1)).put(any(), any()); } + @Test + public void shouldCreateStoreWithSpecificCaches() throws SchemaException, StoreException { + // Given + final Store testStore = new StoreImpl(); + + // When + testStore.initialise("testGraph", new Schema(), StoreProperties.loadStoreProperties("allCaches.properties")); + + // Then + assertThat(CacheServiceLoader.isDefaultEnabled()).isFalse(); + assertThat(CacheServiceLoader.isEnabled("JobTracker")).isTrue(); + assertThat(CacheServiceLoader.isEnabled("NamedView")).isTrue(); + assertThat(CacheServiceLoader.isEnabled("NamedOperation")).isTrue(); + } + + @Test + public void shouldCreateStoreWithDefaultCache() throws SchemaException, StoreException { + // Given + final Store testStore = new StoreImpl(); + final StoreProperties props = new StoreProperties(); + + // When + props.setDefaultCacheServiceClass(HashMapCacheService.class.getName()); + testStore.initialise("testGraph", new Schema(), props); + + // Then + assertThat(CacheServiceLoader.isDefaultEnabled()).isTrue(); + } + @Test public void shouldThrowExceptionIfGraphIdIsNull(@Mock final StoreProperties properties) throws Exception { assertThatIllegalArgumentException().isThrownBy(() -> store.initialise(null, schema, properties)) @@ -480,9 +511,7 @@ public void shouldHandleMultiStepOperations(@Mock final StoreProperties properti @Test public void shouldReturnAllSupportedOperations(@Mock final StoreProperties properties) throws Exception { // Given - final Properties cacheProperties = new Properties(); - cacheProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); - CacheServiceLoader.initialise(cacheProperties); + CacheServiceLoader.initialise(HashMapCacheService.class.getName()); final Schema schema = createSchemaMock(); given(properties.getJobExecutorThreadCount()).willReturn(1); @@ -592,9 +621,7 @@ public void shouldReturnAllSupportedOperations(@Mock final StoreProperties prope @Test public void shouldReturnAllSupportedOperationsWhenJobTrackerIsDisabled(@Mock final StoreProperties properties) throws Exception { // Given - final Properties cacheProperties = new Properties(); - cacheProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); - CacheServiceLoader.initialise(cacheProperties); + CacheServiceLoader.initialise(HashMapCacheService.class.getName()); final Schema schema = createSchemaMock(); given(properties.getJobExecutorThreadCount()).willReturn(1); @@ -1164,12 +1191,10 @@ protected SchemaOptimiser createSchemaOptimiser() { } @Override - protected JobTracker createJobTracker() { + protected void populateCaches() { if (getProperties().getJobTrackerEnabled()) { - return jobTracker; + super.jobTracker = StoreTest.this.jobTracker; } - - return null; } @SuppressWarnings("rawtypes") @@ -1243,12 +1268,10 @@ protected Object doUnhandledOperation(final Operation operation, final Context c } @Override - protected JobTracker createJobTracker() { + protected void populateCaches() { if (getProperties().getJobTrackerEnabled()) { - return jobTracker; + super.jobTracker = StoreTest.this.jobTracker; } - - return null; } @SuppressWarnings("rawtypes") @@ -1358,8 +1381,8 @@ protected SchemaOptimiser createSchemaOptimiser() { } @Override - protected JobTracker createJobTracker() { - return new JobTracker("Test"); + protected void populateCaches() { + super.jobTracker = new JobTracker("Test"); } @SuppressWarnings("rawtypes") diff --git a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/AddNamedViewHandlerTest.java b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/AddNamedViewHandlerTest.java index 7adcd219440..044628a13de 100644 --- a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/AddNamedViewHandlerTest.java +++ b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/AddNamedViewHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,14 +87,9 @@ public void before() throws CacheOperationException { .writeAccessRoles(writeAccessRoles) .build(); - StoreProperties properties = new StoreProperties(); - properties.set("gaffer.cache.service.class", "uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"); - CacheServiceLoader.initialise(properties.getProperties()); + CacheServiceLoader.initialise("uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"); + namedViewCache.clearCache(); given(store.getProperties()).willReturn(new StoreProperties()); - - if (namedViewCache != null && CacheServiceLoader.isEnabled()) { - namedViewCache.clearCache(); - } } @AfterEach diff --git a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/DeleteNamedViewHandlerTest.java b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/DeleteNamedViewHandlerTest.java index b356f8ab330..77971e38e87 100644 --- a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/DeleteNamedViewHandlerTest.java +++ b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/DeleteNamedViewHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,6 @@ public class DeleteNamedViewHandlerTest { private final String invalidNamedViewName = "invalidNamedViewName"; private final String testUserId = "testUser"; private final Map testParameters = new HashMap<>(); - private final StoreProperties properties = new StoreProperties(); private final Context context = new Context(new User.Builder() .userId(testUserId) .opAuth(WRITE_ACCESS_ROLE) @@ -66,9 +65,7 @@ public class DeleteNamedViewHandlerTest { @BeforeEach public void before() throws OperationException { CacheServiceLoader.shutdown(); - - properties.set("gaffer.cache.service.class", "uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"); - CacheServiceLoader.initialise(properties.getProperties()); + CacheServiceLoader.initialise("uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"); given(store.getProperties()).willReturn(new StoreProperties()); diff --git a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/GetAllNamedOperationsHandlerTest.java b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/GetAllNamedOperationsHandlerTest.java index b930aa40c36..856a338804d 100644 --- a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/GetAllNamedOperationsHandlerTest.java +++ b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/GetAllNamedOperationsHandlerTest.java @@ -76,9 +76,7 @@ public void tearDown() { @BeforeEach public void before() { given(store.getProperties()).willReturn(new StoreProperties()); - final StoreProperties properties = new StoreProperties(); - properties.set("gaffer.cache.service.class", "uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"); - CacheServiceLoader.initialise(properties.getProperties()); + CacheServiceLoader.initialise("uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"); } @Test diff --git a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/GetAllNamedViewsHandlerTest.java b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/GetAllNamedViewsHandlerTest.java index f258961c9ee..ea50ce0a58b 100644 --- a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/GetAllNamedViewsHandlerTest.java +++ b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/GetAllNamedViewsHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package uk.gov.gchq.gaffer.store.operation.handler.named; import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -87,22 +86,18 @@ public class GetAllNamedViewsHandlerTest { .readAccessPredicate(new NoAccessPredicate()) .build(); - @BeforeEach - public void beforeEach() throws CacheOperationException { - if (namedViewCache != null && CacheServiceLoader.isEnabled()) { - namedViewCache.clearCache(); - } - } - @AfterAll public static void tearDown() { CacheServiceLoader.shutdown(); } @Test - public void shouldGetAllAccessibleNamedViewsFromCache() throws OperationException { + public void shouldGetAllAccessibleNamedViewsFromCache() throws OperationException, CacheOperationException { // Given - initialiseCache(); + given(store.getProperties()).willReturn(new StoreProperties()); + CacheServiceLoader.initialise("uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"); + namedViewCache.clearCache(); + final NamedViewDetail namedViewAsDetail = new NamedViewDetail.Builder() .name(testNamedViewName) .view(view) @@ -129,11 +124,4 @@ public void shouldGetAllAccessibleNamedViewsFromCache() throws OperationExceptio .contains(namedViewAsDetail) .contains(namedViewAsDetail2); } - - private void initialiseCache() { - given(store.getProperties()).willReturn(new StoreProperties()); - final StoreProperties properties = new StoreProperties(); - properties.set("gaffer.cache.service.class", "uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"); - CacheServiceLoader.initialise(properties.getProperties()); - } } diff --git a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedOperationCacheTest.java b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedOperationCacheTest.java index ac8893061e1..b061d0c0ef5 100644 --- a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedOperationCacheTest.java +++ b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedOperationCacheTest.java @@ -25,7 +25,6 @@ import uk.gov.gchq.gaffer.cache.CacheServiceLoader; import uk.gov.gchq.gaffer.cache.exception.CacheOperationException; import uk.gov.gchq.gaffer.cache.impl.HashMapCacheService; -import uk.gov.gchq.gaffer.cache.util.CacheProperties; import uk.gov.gchq.gaffer.commonutil.exception.OverwritingException; import uk.gov.gchq.gaffer.named.operation.NamedOperationDetail; import uk.gov.gchq.gaffer.operation.OperationChain; @@ -36,7 +35,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Properties; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -84,9 +82,7 @@ public class NamedOperationCacheTest { @BeforeAll public static void setUp() { - final Properties properties = new Properties(); - properties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); - CacheServiceLoader.initialise(properties); + CacheServiceLoader.initialise(HashMapCacheService.class.getName()); cache = new NamedOperationCache(SUFFIX_CACHE_NAME); } diff --git a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCacheBackwardCompatibilityTest.java b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCacheBackwardCompatibilityTest.java index d15ee2bf5fb..288d0bec840 100644 --- a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCacheBackwardCompatibilityTest.java +++ b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCacheBackwardCompatibilityTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 Crown Copyright + * Copyright 2020-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertEquals; +import static uk.gov.gchq.gaffer.store.operation.handler.named.cache.NamedViewCache.NAMED_VIEW_CACHE_SERVICE_NAME; public class NamedViewCacheBackwardCompatibilityTest { private static final String BACKWARDS_COMPATABILITY_2_0_0 = "backwards_compatability_2.0.0"; @@ -43,11 +44,10 @@ public class NamedViewCacheBackwardCompatibilityTest { public static void setUp() { CacheServiceLoader.shutdown(); final Properties properties = new Properties(); - properties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, JcsCacheService.class.getName()); // Note that this config causes a binary resource file containing data to be loaded into the cache // This data includes ADDING_USER and VIEW_NAME properties.setProperty(CacheProperties.CACHE_CONFIG_FILE, GAFFER_2_0_0_CACHE_CACHE_CCF); - CacheServiceLoader.initialise(properties); + CacheServiceLoader.initialise(NAMED_VIEW_CACHE_SERVICE_NAME, JcsCacheService.class.getName(), properties); viewCache = new NamedViewCache(BACKWARDS_COMPATABILITY_2_0_0); } diff --git a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCacheTest.java b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCacheTest.java index 2e952b98357..a47af0115b0 100644 --- a/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCacheTest.java +++ b/core/store/src/test/java/uk/gov/gchq/gaffer/store/operation/handler/named/cache/NamedViewCacheTest.java @@ -25,7 +25,6 @@ import uk.gov.gchq.gaffer.cache.CacheServiceLoader; import uk.gov.gchq.gaffer.cache.exception.CacheOperationException; import uk.gov.gchq.gaffer.cache.impl.HashMapCacheService; -import uk.gov.gchq.gaffer.cache.util.CacheProperties; import uk.gov.gchq.gaffer.commonutil.TestGroups; import uk.gov.gchq.gaffer.commonutil.exception.OverwritingException; import uk.gov.gchq.gaffer.data.elementdefinition.view.NamedViewDetail; @@ -33,7 +32,6 @@ import uk.gov.gchq.gaffer.user.User; import java.util.Arrays; -import java.util.Properties; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -77,9 +75,7 @@ public class NamedViewCacheTest { @BeforeAll public static void setUp() { - final Properties properties = new Properties(); - properties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); - CacheServiceLoader.initialise(properties); + CacheServiceLoader.initialise(HashMapCacheService.class.getName()); cache = new NamedViewCache(SUFFIX_CACHE_NAME); } diff --git a/core/store/src/test/resources/allCaches.properties b/core/store/src/test/resources/allCaches.properties new file mode 100644 index 00000000000..0a823f130d7 --- /dev/null +++ b/core/store/src/test/resources/allCaches.properties @@ -0,0 +1,21 @@ +# +# Copyright 2024 Crown Copyright +# +# 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. +# +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.jobtracker.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.namedview.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.namedoperation.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService + +gaffer.store.job.tracker.enabled=true diff --git a/core/store/src/test/resources/legacyStore.properties b/core/store/src/test/resources/legacyStore.properties new file mode 100644 index 00000000000..66ef8f83374 --- /dev/null +++ b/core/store/src/test/resources/legacyStore.properties @@ -0,0 +1,16 @@ +# +# Copyright 2024 Crown Copyright +# +# 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. +# +gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService diff --git a/core/store/src/test/resources/suffixes.properties b/core/store/src/test/resources/suffixes.properties new file mode 100644 index 00000000000..87d89762520 --- /dev/null +++ b/core/store/src/test/resources/suffixes.properties @@ -0,0 +1,19 @@ +# +# Copyright 2024 Crown Copyright +# +# 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. +# +gaffer.cache.service.default.suffix=default +gaffer.cache.service.job.tracker.suffix=jt +gaffer.cache.service.named.view.suffix=nv +gaffer.cache.service.named.operation.suffix=no diff --git a/example/basic/basic-rest/src/main/resources/map/store.properties b/example/basic/basic-rest/src/main/resources/map/store.properties index 6dd6193e2a1..bba74b4659f 100755 --- a/example/basic/basic-rest/src/main/resources/map/store.properties +++ b/example/basic/basic-rest/src/main/resources/map/store.properties @@ -16,6 +16,6 @@ # Map store config gaffer.store.class=uk.gov.gchq.gaffer.mapstore.SingleUseMapStore # General store config -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService gaffer.store.job.tracker.enabled=true diff --git a/example/federated-demo/src/main/resources/federatedStore.properties b/example/federated-demo/src/main/resources/federatedStore.properties index 36109eaeecf..584e6db0d14 100644 --- a/example/federated-demo/src/main/resources/federatedStore.properties +++ b/example/federated-demo/src/main/resources/federatedStore.properties @@ -14,7 +14,7 @@ # limitations under the License. # gaffer.store.class=uk.gov.gchq.gaffer.federatedstore.FederatedStore -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService gaffer.store.operation.declarations=./operationDeclarations.json # gaffer.federatedstore.storeConfiguredGraphIds=./configuredGraphIdsList.json # gaffer.federatedstore.storeConfiguredMergeFunctions=./configuredMergeFunctionsMap.json diff --git a/example/road-traffic/road-traffic-demo/src/main/resources/map/store.properties b/example/road-traffic/road-traffic-demo/src/main/resources/map/store.properties index 403f3b2810f..ddfaaa040c0 100755 --- a/example/road-traffic/road-traffic-demo/src/main/resources/map/store.properties +++ b/example/road-traffic/road-traffic-demo/src/main/resources/map/store.properties @@ -17,7 +17,7 @@ gaffer.store.class=uk.gov.gchq.gaffer.mapstore.SingleUseMapStore gaffer.store.properties.class=uk.gov.gchq.gaffer.mapstore.MapStoreProperties # General store config -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService gaffer.store.job.tracker.enabled=true gaffer.store.operation.declarations=ExportToOtherAuthorisedGraphOperationDeclarations.json,ExportToOtherGraphOperationDeclarations.json,ResultCacheExportOperations.json diff --git a/example/road-traffic/road-traffic-rest/src/test/resources/accumulo/store.properties b/example/road-traffic/road-traffic-rest/src/test/resources/accumulo/store.properties index b8ccd80ef0a..b70e92a08fb 100644 --- a/example/road-traffic/road-traffic-rest/src/test/resources/accumulo/store.properties +++ b/example/road-traffic/road-traffic-rest/src/test/resources/accumulo/store.properties @@ -21,5 +21,5 @@ accumulo.zookeepers=localhost accumulo.user=user accumulo.password=password # General store config -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService gaffer.store.job.tracker.enabled=true diff --git a/example/road-traffic/road-traffic-rest/src/test/resources/map/store.properties b/example/road-traffic/road-traffic-rest/src/test/resources/map/store.properties index 9edb0dbb66b..da4c4f4fded 100755 --- a/example/road-traffic/road-traffic-rest/src/test/resources/map/store.properties +++ b/example/road-traffic/road-traffic-rest/src/test/resources/map/store.properties @@ -17,5 +17,5 @@ gaffer.store.class=uk.gov.gchq.gaffer.mapstore.SingleUseMapStore gaffer.store.properties.class=uk.gov.gchq.gaffer.mapstore.MapStoreProperties # General store config -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService gaffer.store.job.tracker.enabled=true diff --git a/library/tinkerpop/src/test/resources/gaffer/map-store.properties b/library/tinkerpop/src/test/resources/gaffer/map-store.properties index b9271e137d2..7f1c7ee09e4 100644 --- a/library/tinkerpop/src/test/resources/gaffer/map-store.properties +++ b/library/tinkerpop/src/test/resources/gaffer/map-store.properties @@ -16,4 +16,4 @@ gaffer.store.class=uk.gov.gchq.gaffer.mapstore.MapStore gaffer.store.properties.class=uk.gov.gchq.gaffer.mapstore.MapStoreProperties gaffer.store.mapstore.static=true -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService diff --git a/rest-api/common-rest/src/test/resources/store.properties b/rest-api/common-rest/src/test/resources/store.properties index 710cae9114b..40d1c91828d 100644 --- a/rest-api/common-rest/src/test/resources/store.properties +++ b/rest-api/common-rest/src/test/resources/store.properties @@ -17,4 +17,4 @@ gaffer.store.class=uk.gov.gchq.gaffer.mapstore.SingleUseMapStore gaffer.store.properties.class=uk.gov.gchq.gaffer.mapstore.MapStoreProperties gaffer.store.job.tracker.enabled=true -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService diff --git a/rest-api/core-rest/src/test/resources/persistent-caching-store.properties b/rest-api/core-rest/src/test/resources/persistent-caching-store.properties index 254458fbb1d..e0252671f57 100644 --- a/rest-api/core-rest/src/test/resources/persistent-caching-store.properties +++ b/rest-api/core-rest/src/test/resources/persistent-caching-store.properties @@ -18,5 +18,5 @@ gaffer.store.properties.class=uk.gov.gchq.gaffer.mapstore.MapStoreProperties gaffer.store.job.tracker.enabled=true gaffer.store.job.rescheduleOnStart=true -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService gaffer.cache.config.file=src/test/resources/job-tracker-cache.ccf diff --git a/rest-api/core-rest/src/test/resources/store.properties b/rest-api/core-rest/src/test/resources/store.properties index 710cae9114b..40d1c91828d 100644 --- a/rest-api/core-rest/src/test/resources/store.properties +++ b/rest-api/core-rest/src/test/resources/store.properties @@ -17,4 +17,4 @@ gaffer.store.class=uk.gov.gchq.gaffer.mapstore.SingleUseMapStore gaffer.store.properties.class=uk.gov.gchq.gaffer.mapstore.MapStoreProperties gaffer.store.job.tracker.enabled=true -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService diff --git a/rest-api/spring-rest/src/main/resources/map/store.properties b/rest-api/spring-rest/src/main/resources/map/store.properties index 9d12d203a12..a8766ec156c 100644 --- a/rest-api/spring-rest/src/main/resources/map/store.properties +++ b/rest-api/spring-rest/src/main/resources/map/store.properties @@ -16,5 +16,5 @@ # Map store config gaffer.store.class=uk.gov.gchq.gaffer.mapstore.SingleUseMapStore # General store config -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.JcsCacheService gaffer.store.job.tracker.enabled=true diff --git a/rest-api/spring-rest/src/test/java/uk/gov/gchq/gaffer/rest/integration/controller/JobControllerIT.java b/rest-api/spring-rest/src/test/java/uk/gov/gchq/gaffer/rest/integration/controller/JobControllerIT.java index 97416abdfbf..7a7bb774691 100644 --- a/rest-api/spring-rest/src/test/java/uk/gov/gchq/gaffer/rest/integration/controller/JobControllerIT.java +++ b/rest-api/spring-rest/src/test/java/uk/gov/gchq/gaffer/rest/integration/controller/JobControllerIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 Crown Copyright + * Copyright 2020-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,8 +58,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.when; -import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_CLASS; -import static uk.gov.gchq.gaffer.store.StoreProperties.OPERATION_DECLARATIONS; public class JobControllerIT extends AbstractRestApiIT { @@ -71,8 +69,8 @@ public void setupGraph() { StoreProperties properties = new MapStoreProperties(); properties.setStoreClass(SingleUseMapStore.class); properties.setJobTrackerEnabled(true); - properties.set(CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); - properties.set(OPERATION_DECLARATIONS, "ResultCacheExportOperations.json"); + properties.setDefaultCacheServiceClass(HashMapCacheService.class.getName()); + properties.setOperationDeclarationPaths("ResultCacheExportOperations.json"); Graph graph = new Graph.Builder() .config(new GraphConfig("myGraph")) diff --git a/rest-api/spring-rest/src/test/java/uk/gov/gchq/gaffer/rest/integration/controller/OperationControllerIT.java b/rest-api/spring-rest/src/test/java/uk/gov/gchq/gaffer/rest/integration/controller/OperationControllerIT.java index b1f4632b564..dddbdb24357 100644 --- a/rest-api/spring-rest/src/test/java/uk/gov/gchq/gaffer/rest/integration/controller/OperationControllerIT.java +++ b/rest-api/spring-rest/src/test/java/uk/gov/gchq/gaffer/rest/integration/controller/OperationControllerIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 Crown Copyright + * Copyright 2020-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +56,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; -import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_CLASS; import static uk.gov.gchq.gaffer.core.exception.Status.SERVICE_UNAVAILABLE; import static uk.gov.gchq.gaffer.jsonserialisation.JSONSerialiser.createDefaultMapper; @@ -167,7 +166,7 @@ public void shouldReturnSameJobIdInHeaderAsGetAllJobDetailsOperation() throws IO // Given StoreProperties properties = new MapStoreProperties(); properties.setJobTrackerEnabled(true); - properties.set(CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); + properties.setDefaultCacheServiceClass(HashMapCacheService.class.getName()); Graph graph = new Graph.Builder() .config(StreamUtil.graphConfig(this.getClass())) diff --git a/store-implementation/accumulo-store/src/test/resources/accumuloStoreClassicKeys.properties b/store-implementation/accumulo-store/src/test/resources/accumuloStoreClassicKeys.properties index 5e7d94a78b4..70c0c83d8e3 100644 --- a/store-implementation/accumulo-store/src/test/resources/accumuloStoreClassicKeys.properties +++ b/store-implementation/accumulo-store/src/test/resources/accumuloStoreClassicKeys.properties @@ -23,6 +23,6 @@ accumulo.mini.visibilities=vis1,vis2,publicVisibility,privateVisibility,public,p # General store config -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService gaffer.store.job.tracker.enabled=true gaffer.store.operation.declarations=ExportToOtherAuthorisedGraphOperationDeclarations.json,ExportToOtherGraphOperationDeclarations.json,ResultCacheExportOperations.json,ImportExportOperationDeclarations.json diff --git a/store-implementation/accumulo-store/src/test/resources/cache-store.properties b/store-implementation/accumulo-store/src/test/resources/cache-store.properties index 091966b3977..30d26b92bc6 100644 --- a/store-implementation/accumulo-store/src/test/resources/cache-store.properties +++ b/store-implementation/accumulo-store/src/test/resources/cache-store.properties @@ -16,5 +16,5 @@ gaffer.store.class=uk.gov.gchq.gaffer.mapstore.SingleUseMapStore # Use a small buffer size to test adding in batches gaffer.store.mapstore.map.ingest.buffer.size=5 -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService gaffer.store.job.tracker.enabled=true diff --git a/store-implementation/accumulo-store/src/test/resources/store.properties b/store-implementation/accumulo-store/src/test/resources/store.properties index e272a3edea2..d46d821be66 100644 --- a/store-implementation/accumulo-store/src/test/resources/store.properties +++ b/store-implementation/accumulo-store/src/test/resources/store.properties @@ -21,6 +21,6 @@ accumulo.password=password accumulo.mini.visibilities=vis1,vis2,publicVisibility,privateVisibility,public,private # General store config -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService gaffer.store.job.tracker.enabled=true gaffer.store.operation.declarations=ExportToOtherAuthorisedGraphOperationDeclarations.json,ExportToOtherGraphOperationDeclarations.json,ResultCacheExportOperations.json,ImportExportOperationDeclarations.json diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorage.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorage.java index 5eec725756e..a3199457e17 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorage.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorage.java @@ -16,14 +16,13 @@ package uk.gov.gchq.gaffer.federatedstore; -import com.google.common.collect.Lists; import org.apache.accumulo.core.client.Connector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.gov.gchq.gaffer.accumulostore.AccumuloProperties; import uk.gov.gchq.gaffer.accumulostore.AccumuloStore; -import uk.gov.gchq.gaffer.cache.CacheServiceLoader; +import uk.gov.gchq.gaffer.cache.Cache; import uk.gov.gchq.gaffer.cache.ICache; import uk.gov.gchq.gaffer.cache.exception.CacheOperationException; import uk.gov.gchq.gaffer.commonutil.JsonUtil; @@ -33,11 +32,7 @@ import uk.gov.gchq.gaffer.federatedstore.exception.StorageException; import uk.gov.gchq.gaffer.graph.GraphConfig; import uk.gov.gchq.gaffer.graph.GraphSerialisable; -import uk.gov.gchq.gaffer.jobtracker.JobTracker; -import uk.gov.gchq.gaffer.store.StoreProperties; import uk.gov.gchq.gaffer.store.library.GraphLibrary; -import uk.gov.gchq.gaffer.store.operation.handler.named.cache.NamedOperationCache; -import uk.gov.gchq.gaffer.store.operation.handler.named.cache.NamedViewCache; import uk.gov.gchq.gaffer.user.User; import java.util.ArrayList; @@ -54,7 +49,6 @@ import static java.util.Objects.isNull; import static java.util.Objects.nonNull; import static uk.gov.gchq.gaffer.accumulostore.utils.TableUtils.getConnector; -import static uk.gov.gchq.gaffer.cache.util.CacheProperties.CACHE_SERVICE_CLASS; public class FederatedGraphStorage { public static final String ERROR_ADDING_GRAPH_TO_CACHE = "Error adding graph, GraphId is known within the cache, but %s is different. GraphId: %s"; @@ -69,12 +63,6 @@ public FederatedGraphStorage(final String suffixFederatedStoreCacheName) { federatedStoreCache = new FederatedStoreCache(suffixFederatedStoreCacheName); } - protected void startCacheServiceLoader() throws StorageException { - if (!CacheServiceLoader.isEnabled()) { - throw new StorageException("Cache is not enabled for the FederatedStore, Set a value in StoreProperties for " + CACHE_SERVICE_CLASS); - } - } - /** * places a collections of graphs into storage, protected by the given * access. @@ -201,25 +189,18 @@ private boolean remove(final String graphId, final Predicate ac } private void removeGraphCaches(final String graphId) { - if (CacheServiceLoader.isEnabled()) { - try { - final GraphSerialisable graphFromCache = federatedStoreCache.getGraphFromCache(graphId); - final StoreProperties storeProperties = graphFromCache.getStoreProperties(); - final ArrayList cacheNames = Lists.newArrayList( - NamedViewCache.getCacheNameFrom(storeProperties.getCacheServiceNamedViewSuffix(graphId)), - NamedOperationCache.getCacheNameFrom(storeProperties.getCacheServiceNamedOperationSuffix(graphId)), - JobTracker.getCacheNameFrom(storeProperties.getCacheServiceJobTrackerSuffix(graphId))); - for (final String cacheName : cacheNames) { - final ICache cache = CacheServiceLoader.getService().getCache(cacheName); - if (nonNull(cache)) { - cache.clear(); - } else { - LOGGER.debug(String.format("No cache found graphId:%s with cacheName:%s", graphId, cacheName)); - } + try { + final GraphSerialisable graphFromCache = federatedStoreCache.getGraphFromCache(graphId); + for (final Cache cacheInstance : graphFromCache.getGraph().getCaches()) { + final ICache cache = cacheInstance.getCache(); + if (nonNull(cache)) { + cache.clear(); + } else { + LOGGER.debug(String.format("No cache found graphId:%s with cacheName:%s", graphId, cacheInstance.getCacheName())); } - } catch (final CacheOperationException e) { - throw new GafferRuntimeException(String.format("Error clearing Cache while removing graphId: %s", graphId), e); } + } catch (final CacheOperationException e) { + throw new GafferRuntimeException(String.format("Error clearing Cache while removing graphId: %s", graphId), e); } } diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStore.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStore.java index 1db1052ccbb..992d1c6fc58 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStore.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStore.java @@ -25,6 +25,7 @@ import uk.gov.gchq.gaffer.access.predicate.AccessPredicate; import uk.gov.gchq.gaffer.access.predicate.user.NoAccessUserPredicate; +import uk.gov.gchq.gaffer.cache.CacheServiceLoader; import uk.gov.gchq.gaffer.core.exception.GafferRuntimeException; import uk.gov.gchq.gaffer.data.element.Element; import uk.gov.gchq.gaffer.data.element.id.EntityId; @@ -104,7 +105,10 @@ import static com.google.common.base.Strings.isNullOrEmpty; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; +import static uk.gov.gchq.gaffer.cache.CacheServiceLoader.DEFAULT_SERVICE_NAME; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreCacheTransient.FEDERATED_STORE_CACHE_SERVICE_NAME; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreConstants.FEDERATED_STORE_SYSTEM_USER; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties.CACHE_SERVICE_CLASS_DEFAULT; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties.IS_PUBLIC_ACCESS_ALLOWED_DEFAULT; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties.getCacheServiceFederatedStoreSuffix; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getCleanStrings; @@ -559,14 +563,18 @@ protected Class getRequiredParentSerialiserClass() { @Override protected void startCacheServiceLoader(final StoreProperties properties) { - //this line sets the property map with the default value if required. - properties.setCacheServiceClass(properties.getCacheServiceClass(FederatedStoreProperties.CACHE_SERVICE_CLASS_DEFAULT)); - super.startCacheServiceLoader(properties); - try { - graphStorage.startCacheServiceLoader(); - } catch (final Exception e) { - throw new RuntimeException("Error occurred while starting cache. " + e.getMessage(), e); + final String federatedStoreCacheClass = ((FederatedStoreProperties) properties).getFederatedStoreCacheServiceClass(); + final String defaultCacheClass = properties.getDefaultCacheServiceClass(); + if (federatedStoreCacheClass != null) { + CacheServiceLoader.initialise(FEDERATED_STORE_CACHE_SERVICE_NAME, federatedStoreCacheClass, properties.getProperties()); + } else if (defaultCacheClass != null) { + CacheServiceLoader.initialise(DEFAULT_SERVICE_NAME, defaultCacheClass, properties.getProperties()); + } else { + LOGGER.warn("Federated Store Properties did not include a cache class, using '{}' as default", CACHE_SERVICE_CLASS_DEFAULT); + properties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_DEFAULT); + startCacheServiceLoader(properties); } + super.startCacheServiceLoader(properties); } private void loadCustomPropertiesAuthFromProperties(final FederatedStoreProperties properties) { diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCache.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCache.java index 54653202d40..4353175c0cd 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCache.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCache.java @@ -16,7 +16,6 @@ package uk.gov.gchq.gaffer.federatedstore; -import uk.gov.gchq.gaffer.cache.Cache; import uk.gov.gchq.gaffer.cache.ICache; import uk.gov.gchq.gaffer.cache.exception.CacheOperationException; import uk.gov.gchq.gaffer.commonutil.pair.Pair; @@ -27,14 +26,13 @@ import uk.gov.gchq.gaffer.jsonserialisation.JSONSerialiser; /** - * Wrapper around the {@link uk.gov.gchq.gaffer.cache.CacheServiceLoader} to provide an interface for - * handling the {@link Graph}s within a {@link uk.gov.gchq.gaffer.federatedstore.FederatedStore}. + * Wrapper around {@link FederatedStoreCacheTransient} to provide an interface for + * handling {@link Graph}s within a {@link FederatedStore}. */ -public class FederatedStoreCache extends Cache> { +public final class FederatedStoreCache { private final FederatedStoreCacheTransient cacheTransient; public FederatedStoreCache(final String suffixFederatedStoreCacheName) { - super(null); cacheTransient = new FederatedStoreCacheTransient(suffixFederatedStoreCacheName); } @@ -126,7 +124,6 @@ public FederatedAccess getAccessFromCache(final String graphId) { } } - @Override public Pair getFromCache(final String key) { try { final Pair fromCache = cacheTransient.getFromCache(key); @@ -136,32 +133,26 @@ public Pair getFromCache(final String key) { } } - @Override public String getCacheName() { return cacheTransient.getCacheName(); } - @Override public Iterable getAllKeys() { return cacheTransient.getAllKeys(); } - @Override public void clearCache() throws CacheOperationException { cacheTransient.clearCache(); } - @Override public boolean contains(final String graphId) { return cacheTransient.contains(graphId); } - @Override public void deleteFromCache(final String key) { cacheTransient.deleteFromCache(key); } - @Override public ICache getCache() { return cacheTransient.getCache(); } diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheTransient.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheTransient.java index a4de074c2ee..4879fa3c066 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheTransient.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheTransient.java @@ -23,15 +23,16 @@ import uk.gov.gchq.gaffer.graph.GraphSerialisable; /** - * Wrapper around the {@link uk.gov.gchq.gaffer.cache.CacheServiceLoader} to provide an interface for - * handling the {@link Graph}s within a {@link FederatedStore}. + * Implementation of {@link Cache} for handling + * {@link Graph}s within a {@link FederatedStore}. */ public class FederatedStoreCacheTransient extends Cache> { public static final String ERROR_ADDING_GRAPH_TO_CACHE_GRAPH_ID_S = "Error adding graph to cache. graphId: %s"; private static final String CACHE_SERVICE_NAME_PREFIX = "federatedStoreGraphs"; + public static final String FEDERATED_STORE_CACHE_SERVICE_NAME = "FederatedStore"; public FederatedStoreCacheTransient(final String suffixFederatedStoreCacheName) { - super(getCacheNameFrom(suffixFederatedStoreCacheName)); + super(getCacheNameFrom(suffixFederatedStoreCacheName), FEDERATED_STORE_CACHE_SERVICE_NAME); } public static String getCacheNameFrom(final String suffixFederatedStoreCacheName) { diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreProperties.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreProperties.java index 076fb101aec..648b8859349 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreProperties.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,6 +45,10 @@ public class FederatedStoreProperties extends StoreProperties { public static final String STORE_CONFIGURED_MERGE_FUNCTIONS = "gaffer.federatedstore.storeConfiguredMergeFunctions"; public static final String STORE_CONFIGURED_GRAPHIDS = "gaffer.federatedstore.storeConfiguredGraphIds"; public static final String CACHE_SERVICE_FEDERATED_STORE_SUFFIX = "gaffer.cache.service.federated.store.suffix"; + /** + * Name of the system property to use for defining a cache service class dedicated to the Federated Store. + */ + public static final String CACHE_SERVICE_FEDERATED_STORE_CLASS = "gaffer.cache.service.federatedstore.class"; public FederatedStoreProperties() { super(FederatedStore.class); @@ -113,4 +117,12 @@ public String getCacheServiceFederatedStoreSuffix(final String defaultValue) { public static String getCacheServiceFederatedStoreSuffix(final StoreProperties properties, final String defaultValue) { return properties.get(CACHE_SERVICE_FEDERATED_STORE_SUFFIX, properties.getCacheServiceDefaultSuffix(defaultValue)); } + + public String getFederatedStoreCacheServiceClass() { + return get(CACHE_SERVICE_FEDERATED_STORE_CLASS); + } + + public void setFederatedStoreCacheServiceClass(final String cacheServiceClassString) { + set(CACHE_SERVICE_FEDERATED_STORE_CLASS, cacheServiceClassString); + } } diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/FederatedAddGraphHandlerParent.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/FederatedAddGraphHandlerParent.java index 76d00838287..23b3b43835b 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/FederatedAddGraphHandlerParent.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/FederatedAddGraphHandlerParent.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 Crown Copyright + * Copyright 2018-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,14 +32,13 @@ import uk.gov.gchq.gaffer.operation.io.Output; import uk.gov.gchq.gaffer.store.Context; import uk.gov.gchq.gaffer.store.Store; -import uk.gov.gchq.gaffer.store.StoreProperties; import uk.gov.gchq.gaffer.store.operation.handler.OperationHandler; import uk.gov.gchq.gaffer.user.User; -import static java.util.Objects.isNull; -import static java.util.Objects.nonNull; -import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties.CACHE_SERVICE_CLASS_DEFAULT; -import static uk.gov.gchq.gaffer.store.StoreProperties.CACHE_SERVICE_CLASS; +import java.util.Properties; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; /** * A handler for operations that addGraph to the FederatedStore. @@ -59,11 +58,14 @@ public Void doOperation(final OP operation, final Context context, final Store s final User user = context.getUser(); final boolean isLimitedToLibraryProperties = ((FederatedStore) store).isLimitedToLibraryProperties(user, operation.isUserRequestingAdminUsage()); - if (isLimitedToLibraryProperties && nonNull(operation.getStoreProperties())) { + if (isLimitedToLibraryProperties && (operation.getStoreProperties() != null)) { throw new OperationException(String.format(USER_IS_LIMITED_TO_ONLY_USING_PARENT_PROPERTIES_ID_FROM_GRAPHLIBRARY_BUT_FOUND_STORE_PROPERTIES_S, operation.getProperties().toString())); } - overwriteCacheProperty(operation, store); + // If the operation has store properties, check them for conflicts with existing cache configuration + if (operation.getStoreProperties() != null) { + checkCacheProperties(operation, store); + } final GraphSerialisable graphSerialisable; try { @@ -95,17 +97,31 @@ public Void doOperation(final OP operation, final Context context, final Store s return null; } - private void overwriteCacheProperty(final OP operation, final Store store) { - /* - * FederatedStore can't survive if a subgraph changes the static - * cache to another cache, or re-initialises the cache. - */ - final String cacheServiceClass = isNull(store.getProperties()) ? null : store.getProperties().getCacheServiceClass(CACHE_SERVICE_CLASS_DEFAULT); - final StoreProperties storeProperties = operation.getStoreProperties(); - if (nonNull(storeProperties) && !storeProperties.getCacheServiceClass(cacheServiceClass).equals(cacheServiceClass)) { - LOGGER.info(String.format("Removing %s from properties of the operation and substituting the FederatedStore's cache", CACHE_SERVICE_CLASS)); - storeProperties.setCacheServiceClass(cacheServiceClass); - operation.setStoreProperties(storeProperties); + /** + * Warns users when their specified cache config may be ignored + *

+ * FederatedStore initialises its own cache(s) and a subgraph cannot + * re-initialise these. If an added graph tries to initialise a cache + * class which was already initialised, then this is ignored and the + * existing cache service is used instead. + * + * @param operation {@link Operation} adding a new subgraph + * @param store existing federated {@link Store} + */ + private void checkCacheProperties(final OP operation, final Store store) { + final Properties operationProperties = operation.getStoreProperties().getProperties(); + final Properties storeProperties = store.getProperties().getProperties(); + Predicate matchCacheClassPredicate = (key) -> ((String) key).matches("^gaffer\\.cache\\.service\\..*class$"); + final boolean propertiesContainCacheConfig = operationProperties.keySet().stream().anyMatch(matchCacheClassPredicate); + + if (propertiesContainCacheConfig) { + LOGGER.info("Graph '{}' specifies Cache class(s), which will be ignored if they are already initialised.", operation.getGraphId()); + Set initCacheProps = storeProperties.keySet().stream().filter(matchCacheClassPredicate).collect(Collectors.toSet()); + Set opCacheProps = operationProperties.keySet().stream().filter(matchCacheClassPredicate).collect(Collectors.toSet()); + initCacheProps.retainAll(opCacheProps); // Intersection of existing props and operation props, indicates conflicting props unless empty + if (!initCacheProps.isEmpty()) { + LOGGER.warn("Graph '{}' specifies property {} - will be ignored as these cache(s) were already initialised by the Federated Store.", operation.getGraphId(), initCacheProps); + } } } diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/AdminGetAllGraphInfoTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/AdminGetAllGraphInfoTest.java index e3583bd2a5b..936980f812c 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/AdminGetAllGraphInfoTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/AdminGetAllGraphInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 Crown Copyright + * Copyright 2020-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,7 @@ import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.ACCUMULO_STORE_SINGLE_USE_PROPERTIES; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GRAPH_ID_ACCUMULO; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GRAPH_ID_TEST_FEDERATED_STORE; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.getFederatedStorePropertiesWithHashMapCache; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.loadAccumuloStoreProperties; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.resetForFederatedTests; import static uk.gov.gchq.gaffer.user.StoreUser.AUTH_1; @@ -60,7 +61,7 @@ public void setUp() throws Exception { resetForFederatedTests(); access = new FederatedAccess(singleton(AUTH_1), AUTH_USER_ID, false); store = new FederatedStore(); - final StoreProperties storeProperties = new StoreProperties(); + final FederatedStoreProperties storeProperties = getFederatedStorePropertiesWithHashMapCache(); storeProperties.set(StoreProperties.ADMIN_AUTH, ADMIN_AUTH); store.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, storeProperties); } diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedAccessResourceAccessPredicateTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedAccessResourceAccessPredicateTest.java index 41e52b07829..ca4a04877c8 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedAccessResourceAccessPredicateTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedAccessResourceAccessPredicateTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 Crown Copyright + * Copyright 2020-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -109,9 +109,7 @@ public void shouldBeSerialisableUsingCacheWhenUsingCustomPredicate() throws Exce .writeAccessPredicate(new AccessPredicate(new CustomUserPredicate())) .build(); - final StoreProperties storeProperties = new StoreProperties(); - storeProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_DEFAULT); - CacheServiceLoader.initialise(storeProperties.getProperties()); + CacheServiceLoader.initialise(CACHE_SERVICE_CLASS_DEFAULT); final FederatedStoreCache testCache = new FederatedStoreCache("shouldBeSerialisableWithCacheWhenUsingCustomPredicate"); final String testKey = "testKey"; diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorageTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorageTest.java index 862d1fff0d5..46acb04cedd 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorageTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorageTest.java @@ -26,8 +26,6 @@ import uk.gov.gchq.gaffer.accumulostore.AccumuloProperties; import uk.gov.gchq.gaffer.cache.CacheServiceLoader; import uk.gov.gchq.gaffer.cache.ICacheService; -import uk.gov.gchq.gaffer.cache.impl.HashMapCacheService; -import uk.gov.gchq.gaffer.cache.util.CacheProperties; import uk.gov.gchq.gaffer.federatedstore.exception.StorageException; import uk.gov.gchq.gaffer.graph.GraphConfig; import uk.gov.gchq.gaffer.graph.GraphSerialisable; @@ -40,7 +38,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.Properties; import java.util.Set; import static java.util.Collections.singleton; @@ -48,8 +45,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static uk.gov.gchq.gaffer.federatedstore.FederatedGraphStorage.GRAPH_IDS_NOT_VISIBLE; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreCacheTransient.getCacheNameFrom; @@ -96,9 +91,7 @@ public class FederatedGraphStorageTest { @BeforeEach public void setUp() throws Exception { resetForFederatedTests(); - FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_DEFAULT); - CacheServiceLoader.initialise(federatedStoreProperties.getProperties()); + CacheServiceLoader.initialise(CACHE_SERVICE_CLASS_DEFAULT); graphStorage = new FederatedGraphStorage(CACHE_NAME_SUFFIX); } @@ -301,7 +294,7 @@ public void shouldRemoveForOwningUser() throws Exception { final boolean remove = graphStorage.remove(GRAPH_ID_A, testUser(), false); final Collection graphs = graphStorage.getAll(testUser()); //when - assertTrue(remove); + assertThat(remove).isTrue(); assertThat(graphs).isEmpty(); } @@ -313,7 +306,7 @@ public void shouldNotRemoveForOwningUserWhenBlockingWriteAccessPredicateConfigur final boolean remove = graphStorage.remove(GRAPH_ID_A, testUser(), false); final Collection graphs = graphStorage.getAll(testUser()); //then - assertFalse(remove); + assertThat(remove).isFalse(); assertThat(graphs).containsExactly(graphSerialisableA); } @@ -324,7 +317,7 @@ public void shouldNotRemoveForAuthUser() throws Exception { //when final boolean remove = graphStorage.remove(GRAPH_ID_A, authUser(), false); //then - assertFalse(remove); + assertThat(remove).isFalse(); } @Test @@ -334,7 +327,7 @@ public void shouldNotRemoveForBlankUser() throws Exception { //when final boolean remove = graphStorage.remove(GRAPH_ID_A, blankUser(), false); //then - assertFalse(remove); + assertThat(remove).isFalse(); } @Test @@ -344,7 +337,7 @@ public void shouldRemoveForBlankUserWhenPermissiveWriteAccessPredicateConfigured //when final boolean remove = graphStorage.remove(GRAPH_ID_A, blankUser(), false); //then - assertTrue(remove); + assertThat(remove).isTrue(); } @Test @@ -534,15 +527,10 @@ private SchemaEntityDefinition getEntityDefinition(final int i) { .build(); } - @Test public void shouldAddGraphWithCacheEnabled() throws StorageException { //given - final Properties serviceLoaderProperties = new Properties(); - serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); - CacheServiceLoader.initialise(serviceLoaderProperties); - graphStorage.startCacheServiceLoader(); - final ICacheService cacheService = CacheServiceLoader.getService(); + final ICacheService cacheService = CacheServiceLoader.getDefaultService(); //when graphStorage.put(graphSerialisableA, auth1Access); @@ -552,21 +540,15 @@ public void shouldAddGraphWithCacheEnabled() throws StorageException { assertThat(cacheService.getCache(getCacheNameFrom(CACHE_NAME_SUFFIX)).getAllValues()).hasSize(1); assertThat(allIds).hasSize(1); assertThat(allIds.iterator().next()).isEqualTo(GRAPH_ID_A); - } @Test public void shouldAddGraphReplicatedBetweenInstances() throws StorageException { //given - final Properties serviceLoaderProperties = new Properties(); - serviceLoaderProperties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, HashMapCacheService.class.getName()); - CacheServiceLoader.initialise(serviceLoaderProperties); - final ICacheService cacheService = CacheServiceLoader.getService(); + final ICacheService cacheService = CacheServiceLoader.getDefaultService(); final FederatedGraphStorage otherGraphStorage = new FederatedGraphStorage(CACHE_NAME_SUFFIX); - graphStorage.startCacheServiceLoader(); //when - otherGraphStorage.startCacheServiceLoader(); otherGraphStorage.put(graphSerialisableA, auth1Access); final Collection allIds = graphStorage.getAllIds(authUser()); @@ -574,7 +556,6 @@ public void shouldAddGraphReplicatedBetweenInstances() throws StorageException { assertThat(cacheService.getCache(getCacheNameFrom(CACHE_NAME_SUFFIX)).getAllValues()).hasSize(1); assertThat(allIds).hasSize(1); assertThat(allIds.iterator().next()).isEqualTo(GRAPH_ID_A); - } } diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreAuthTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreAuthTest.java index 287f0a0fe5c..654cca7e7c8 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreAuthTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreAuthTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ public void setUp() throws Exception { FederatedStoreProperties federatedStoreProperties; federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); federatedStore.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, federatedStoreProperties); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheBackwardCompatibilityTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheBackwardCompatibilityTest.java index f6e062b728e..a017078cc52 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheBackwardCompatibilityTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheBackwardCompatibilityTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 Crown Copyright + * Copyright 2020-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertEquals; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreCacheTransient.FEDERATED_STORE_CACHE_SERVICE_NAME; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GRAPH_ID_MAP; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.MAP_STORE_SINGLE_USE_PROPERTIES; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.SCHEMA_EDGE_BASIC_JSON; @@ -60,12 +61,11 @@ public void setUp() { resetForFederatedTests(); Properties properties = new Properties(); - properties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, JcsCacheService.class.getName()); // Note that this config causes a binary resource file containing data to be loaded into the cache // This data includes MAP_ID_1 and user auths properties.setProperty(CacheProperties.CACHE_CONFIG_FILE, GAFFER_2_1_0_CACHE_CACHE_CCF); - CacheServiceLoader.initialise(properties); + CacheServiceLoader.initialise(FEDERATED_STORE_CACHE_SERVICE_NAME, JcsCacheService.class.getName(), properties); federatedStoreCache = new FederatedStoreCache(BACKWARDS_COMPATABILITY_2_1_0); new Graph.Builder().config(new GraphConfig(GRAPH_ID_MAP)) diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheSuffixTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheSuffixTest.java index afb0286ad4e..c27e9a84f03 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheSuffixTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheSuffixTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Crown Copyright + * Copyright 2023-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,13 +18,13 @@ import org.junit.jupiter.api.Test; +import uk.gov.gchq.gaffer.cache.util.CacheProperties; import uk.gov.gchq.gaffer.graph.Graph; import uk.gov.gchq.gaffer.graph.GraphConfig; import uk.gov.gchq.gaffer.graph.hook.NamedOperationResolver; import uk.gov.gchq.gaffer.graph.hook.NamedViewResolver; import uk.gov.gchq.gaffer.graph.hook.exception.GraphHookSuffixException; import uk.gov.gchq.gaffer.named.operation.NamedOperation; -import uk.gov.gchq.gaffer.store.StoreProperties; import uk.gov.gchq.gaffer.store.operation.handler.named.AddNamedOperationHandler; import uk.gov.gchq.gaffer.store.operation.handler.named.AddNamedViewHandler; import uk.gov.gchq.gaffer.store.operation.handler.named.NamedOperationHandler; @@ -120,7 +120,7 @@ void shouldNotAllowResolverWithDifferentSuffixToBeMismatchedWithAddNamedViewHand @Test void shouldNotAllowResolverWithNullSuffixToBeMismatchedWithNamedOperationHandlersDefaultSuffix() { final FederatedStoreProperties properties = new FederatedStoreProperties(); - properties.set(StoreProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); // Configure builder Graph.Builder builder = new Graph.Builder() @@ -141,7 +141,7 @@ void shouldNotAllowResolverWithNullSuffixToBeMismatchedWithNamedOperationHandler @Test void shouldNotAllowResolverWithNullSuffixToBeMismatchedWithNamedViewHandlersDefaultSuffix() { final FederatedStoreProperties properties = new FederatedStoreProperties(); - properties.set(StoreProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); // Configure builder Graph.Builder builder = new Graph.Builder() @@ -162,7 +162,7 @@ void shouldNotAllowResolverWithNullSuffixToBeMismatchedWithNamedViewHandlersDefa @Test void shouldNotAllowResolverWithDifferentSuffixToBeMismatchedWithNamedOperationHandlersDefaultSuffix() { final FederatedStoreProperties properties = new FederatedStoreProperties(); - properties.set(StoreProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); // Configure builder Graph.Builder builder = new Graph.Builder() @@ -184,7 +184,7 @@ void shouldNotAllowResolverWithDifferentSuffixToBeMismatchedWithNamedOperationHa @Test void shouldNotAllowResolverWithDifferentSuffixToBeMismatchedWithNamedViewHandlersDefaultSuffix() { final FederatedStoreProperties properties = new FederatedStoreProperties(); - properties.set(StoreProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); // Configure builder Graph.Builder builder = new Graph.Builder() @@ -206,8 +206,8 @@ void shouldNotAllowResolverWithDifferentSuffixToBeMismatchedWithNamedViewHandler @Test void shouldNotAllowResolverWithNullSuffixToBeMismatchedWithNamedOperationHandlersServiceNamedOperationSuffix() { final FederatedStoreProperties properties = new FederatedStoreProperties(); - properties.set(StoreProperties.CACHE_SERVICE_DEFAULT_SUFFIX, IGNORE_SUFFIX); - properties.set(StoreProperties.CACHE_SERVICE_NAMED_OPERATION_SUFFIX, PRIORITY_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX, IGNORE_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_NAMED_OPERATION_SUFFIX, PRIORITY_SUFFIX); // Configure builder Graph.Builder builder = new Graph.Builder() @@ -228,8 +228,8 @@ void shouldNotAllowResolverWithNullSuffixToBeMismatchedWithNamedOperationHandler @Test void shouldNotAllowResolverWithNullSuffixToBeMismatchedWithNamedViewHandlersServiceNamedViewSuffix() { final FederatedStoreProperties properties = new FederatedStoreProperties(); - properties.set(StoreProperties.CACHE_SERVICE_DEFAULT_SUFFIX, IGNORE_SUFFIX); - properties.set(StoreProperties.CACHE_SERVICE_NAMED_VIEW_SUFFIX, PRIORITY_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX, IGNORE_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_NAMED_VIEW_SUFFIX, PRIORITY_SUFFIX); // Configure builder Graph.Builder builder = new Graph.Builder() @@ -250,8 +250,8 @@ void shouldNotAllowResolverWithNullSuffixToBeMismatchedWithNamedViewHandlersServ @Test void shouldNotAllowResolverWithDifferentSuffixToBeMismatchedWithNamedOperationHandlersServiceNamedOperationSuffix() { final FederatedStoreProperties properties = new FederatedStoreProperties(); - properties.set(StoreProperties.CACHE_SERVICE_DEFAULT_SUFFIX, IGNORE_SUFFIX); - properties.set(StoreProperties.CACHE_SERVICE_NAMED_OPERATION_SUFFIX, PRIORITY_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX, IGNORE_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_NAMED_OPERATION_SUFFIX, PRIORITY_SUFFIX); // Configure builder Graph.Builder builder = new Graph.Builder() @@ -273,8 +273,8 @@ void shouldNotAllowResolverWithDifferentSuffixToBeMismatchedWithNamedOperationHa @Test void shouldNotAllowResolverWithDifferentSuffixToBeMismatchedWithNamedViewHandlersServiceNamedOperationSuffix() { final FederatedStoreProperties properties = new FederatedStoreProperties(); - properties.set(StoreProperties.CACHE_SERVICE_DEFAULT_SUFFIX, IGNORE_SUFFIX); - properties.set(StoreProperties.CACHE_SERVICE_NAMED_VIEW_SUFFIX, PRIORITY_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX, IGNORE_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_NAMED_VIEW_SUFFIX, PRIORITY_SUFFIX); // Configure builder Graph.Builder builder = new Graph.Builder() @@ -296,7 +296,7 @@ void shouldNotAllowResolverWithDifferentSuffixToBeMismatchedWithNamedViewHandler @Test void ShouldAddMissingResolvers() throws Exception { final FederatedStoreProperties properties = new FederatedStoreProperties(); - properties.set(StoreProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); + properties.set(CacheProperties.CACHE_SERVICE_DEFAULT_SUFFIX, DEFAULT_SUFFIX); final Graph graph = new Graph.Builder() .config(new GraphConfig.Builder() diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheTest.java index e08e70b5775..3cb0d6f2276 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreCacheTest.java @@ -22,14 +22,11 @@ import uk.gov.gchq.gaffer.cache.CacheServiceLoader; import uk.gov.gchq.gaffer.cache.exception.CacheOperationException; -import uk.gov.gchq.gaffer.cache.util.CacheProperties; import uk.gov.gchq.gaffer.commonutil.exception.OverwritingException; import uk.gov.gchq.gaffer.graph.Graph; import uk.gov.gchq.gaffer.graph.GraphConfig; import uk.gov.gchq.gaffer.graph.GraphSerialisable; -import java.util.Properties; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.from; @@ -50,10 +47,7 @@ public class FederatedStoreCacheTest { public static void setUp() { resetForFederatedTests(); - Properties properties = new Properties(); - properties.setProperty(CacheProperties.CACHE_SERVICE_CLASS, CACHE_SERVICE_CLASS_STRING); - CacheServiceLoader.initialise(properties); - + CacheServiceLoader.initialise(CACHE_SERVICE_CLASS_STRING); federatedStoreCache = new FederatedStoreCache("GRAPH_ID_ACCUMULO"); testGraph = new Graph.Builder().config(new GraphConfig(GRAPH_ID_ACCUMULO)) .addStoreProperties(loadAccumuloStoreProperties(ACCUMULO_STORE_SINGLE_USE_PROPERTIES)) diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGetWalksTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGetWalksTest.java index a01944dc93c..2b7624a4ba0 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGetWalksTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGetWalksTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Crown Copyright + * Copyright 2023-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,7 +75,7 @@ public static void tearDownCache() { public void setUp() throws Exception { resetForFederatedTests(); FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); federatedGraph = new Graph.Builder() .config(new GraphConfig.Builder() diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGraphLibraryTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGraphLibraryTest.java index 45d29ae3c37..da06128b82e 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGraphLibraryTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGraphLibraryTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,7 +80,7 @@ public void setUp() throws Exception { federatedStore = new FederatedStore(); FederatedStoreProperties fedProperties = new FederatedStoreProperties(); - fedProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + fedProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); federatedStore.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, fedProperties); federatedStore.setGraphLibrary(library); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGraphVisibilityTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGraphVisibilityTest.java index b5769d77859..30301954487 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGraphVisibilityTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreGraphVisibilityTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,7 +70,7 @@ public static void tearDownCache() { public void setUp() throws Exception { resetForFederatedTests(); FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); federatedGraph = new Builder() .config(new GraphConfig.Builder() diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreMultiCacheTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreMultiCacheTest.java index 74f2710d37d..fb156e14af6 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreMultiCacheTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreMultiCacheTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +58,7 @@ public void setUp() throws Exception { resetForFederatedTests(); federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); federatedStoreProperties.set(HashMapCacheService.STATIC_CACHE, String.valueOf(true)); federatedStoreProperties.setCacheServiceNameSuffix(USER_SAME_CACHE_SUFFIX); federatedStore = new FederatedStore(); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStorePropertiesTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStorePropertiesTest.java new file mode 100644 index 00000000000..98fdc5be1b6 --- /dev/null +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStorePropertiesTest.java @@ -0,0 +1,113 @@ +/* + * Copyright 2024 Crown Copyright + * + * 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 uk.gov.gchq.gaffer.federatedstore; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import uk.gov.gchq.gaffer.commonutil.StreamUtil; + +import java.io.InputStream; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.assertj.core.api.Assertions.assertThat; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.CACHE_SERVICE_CLASS_STRING; + +public class FederatedStorePropertiesTest { + final String key = "gaffer.store.class"; + final String value = FederatedStore.class.getName(); + static Path propertiesFilePath; + + @BeforeAll + static void init() throws URISyntaxException { + propertiesFilePath = Paths.get(FederatedStorePropertiesTest.class.getResource("/properties/federatedStore.properties").toURI()); + } + + @Test + void shouldGetIsPublicAccessAllowed() { + // Given / When + final FederatedStoreProperties props = new FederatedStoreProperties(); + // Then + assertThat(props.getIsPublicAccessAllowed()).isEqualTo("true"); + } + + @Test + void shouldGetAndSetStoreConfiguredMergeFunctions() { + // Given / When + final FederatedStoreProperties props = new FederatedStoreProperties(); + // Then + assertThat(props.getStoreConfiguredMergeFunctions()).isNull(); + + // Given / When + props.setStoreConfiguredMergeFunctions(FederatedStorePropertiesTest.class.getResource("/integrationTestMergeFunctions.json").toString()); + // Then + assertThat(props.getStoreConfiguredMergeFunctions()).isNotNull(); + } + + @Test + void shouldGetCacheServiceFederatedStoreSuffix() { + // Given / When + final FederatedStoreProperties props = new FederatedStoreProperties(); + // Then + assertThat(props.getCacheServiceFederatedStoreSuffix(null)).isNull(); + assertThat(props.getCacheServiceFederatedStoreSuffix("true")).isNotNull(); + } + + @Test + void shouldGetAndSetFederatedStoreCacheServiceClass() { + // Given / When + final FederatedStoreProperties props = new FederatedStoreProperties(); + // Then + assertThat(props.getFederatedStoreCacheServiceClass()).isNull(); + // Given / When + props.setFederatedStoreCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + // Then + assertThat(props.getFederatedStoreCacheServiceClass()).isEqualTo(CACHE_SERVICE_CLASS_STRING); + } + + @Test + void shouldReturnFederatedStorePropertiesFromPath() { + // Given / When + FederatedStoreProperties props = FederatedStoreProperties.loadStoreProperties(propertiesFilePath); + // Then + assertThat(props.get(key)).isEqualTo(value); + assertThat(props.getClass()).isEqualTo(FederatedStoreProperties.class); + } + + @Test + void shouldReturnFederatedStorePropertiesFromPathString() { + // Given + String propsPathString = propertiesFilePath.toString(); + // When + FederatedStoreProperties props = FederatedStoreProperties.loadStoreProperties(propsPathString); + // Then + assertThat(props.get(key)).isEqualTo(value); + assertThat(props.getClass()).isEqualTo(FederatedStoreProperties.class); + } + + @Test + void shouldReturnFederatedStorePropertiesFromInputStream() { + // Given + InputStream inputStream = StreamUtil.openStream(FederatedStorePropertiesTest.class, "properties/federatedStore.properties"); + // When + FederatedStoreProperties props = FederatedStoreProperties.loadStoreProperties(inputStream, FederatedStoreProperties.class); + // Then + assertThat(props.getClass()).isEqualTo(FederatedStoreProperties.class); + } +} diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStorePublicAccessTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStorePublicAccessTest.java index db06a027e2b..84e992b7ce0 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStorePublicAccessTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStorePublicAccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,7 +64,7 @@ public void setUp() throws Exception { resetForFederatedTests(); federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); store = new FederatedStore(); } diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreSchemaTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreSchemaTest.java index 55c4d9eb44e..693a94d07c7 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreSchemaTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreSchemaTest.java @@ -72,6 +72,7 @@ import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.VALUE_1; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.VALUE_2; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.contextTestUser; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.getFederatedStorePropertiesWithHashMapCache; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.loadAccumuloStoreProperties; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.property; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.resetForFederatedTests; @@ -108,7 +109,7 @@ public void setUp() throws Exception { resetForFederatedTests(); federatedStore = new FederatedStore(); - federatedStore.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, new FederatedStoreProperties()); + federatedStore.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, getFederatedStorePropertiesWithHashMapCache()); testUser = testUser(); testContext = contextTestUser(); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTest.java index 095c2adf324..ad12c9de152 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -95,6 +95,7 @@ import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.SCHEMA_ENTITY_B_JSON; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.SOURCE_BASIC; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.contextBlankUser; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.getFederatedStorePropertiesWithHashMapCache; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.loadAccumuloStoreProperties; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.resetForFederatedTests; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getCleanStrings; @@ -148,7 +149,7 @@ public static void cleanUp() { public void setUp() throws Exception { resetForFederatedTests(); - federatedProperties = new FederatedStoreProperties(); + federatedProperties = getFederatedStorePropertiesWithHashMapCache(); federatedProperties.set(HashMapCacheService.STATIC_CACHE, String.valueOf(true)); properties1 = loadAccumuloStoreProperties(ACCUMULO_STORE_SINGLE_USE_PROPERTIES); @@ -920,7 +921,7 @@ private List toGraphs(final Collection graphSerialisab @Test public void shouldThrowExceptionWithInvalidCacheClass() { - federatedProperties.setCacheServiceClass(INVALID_CACHE_SERVICE_CLASS_STRING); + federatedProperties.setDefaultCacheServiceClass(INVALID_CACHE_SERVICE_CLASS_STRING); CacheServiceLoader.shutdown(); @@ -932,8 +933,8 @@ public void shouldThrowExceptionWithInvalidCacheClass() { public void shouldReuseGraphsAlreadyInCache() throws Exception { // Check cache is empty CacheServiceLoader.shutdown(); - federatedProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); - assertThat(CacheServiceLoader.getService()).isNull(); + federatedProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + assertThat(CacheServiceLoader.getDefaultService()).isNull(); // initialise FedStore store.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, federatedProperties); @@ -949,7 +950,7 @@ public void shouldReuseGraphsAlreadyInCache() throws Exception { // check the store and the cache assertThat(store.getAllGraphIds(blankUser)).hasSize(1); - assertThat(CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME)) + assertThat(CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME)) .contains(ACC_ID_2, ACC_ID_2); // restart the store @@ -957,24 +958,24 @@ public void shouldReuseGraphsAlreadyInCache() throws Exception { store.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, federatedProperties); // check the graph is already in there from the cache - assertThat(CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME)) - .withFailMessage(String.format("Keys: %s did not contain %s", CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME), ACC_ID_2)).contains(ACC_ID_2); + assertThat(CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME)) + .withFailMessage(String.format("Keys: %s did not contain %s", CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME), ACC_ID_2)).contains(ACC_ID_2); assertThat(store.getAllGraphIds(blankUser)).hasSize(1); } @Test public void shouldInitialiseWithCache() throws StoreException { CacheServiceLoader.shutdown(); - assertThat(CacheServiceLoader.getService()).isNull(); - federatedProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); - assertThat(CacheServiceLoader.getService()).isNull(); + assertThat(CacheServiceLoader.getDefaultService()).isNull(); + federatedProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + assertThat(CacheServiceLoader.getDefaultService()).isNull(); store.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, federatedProperties); - assertThat(CacheServiceLoader.getService()).isNotNull(); + assertThat(CacheServiceLoader.getDefaultService()).isNotNull(); } @Test public void shouldThrowExceptionWithoutInitialisation() throws StoreException { - federatedProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); store.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, federatedProperties); // Given @@ -989,7 +990,7 @@ public void shouldThrowExceptionWithoutInitialisation() throws StoreException { // When / Then assertThatExceptionOfType(Exception.class) .isThrownBy(() -> store.addGraphs(null, TEST_USER_ID, false, graphToAdd)) - .withStackTraceContaining("Cache is not enabled, check it was Initialised"); + .withStackTraceContaining("Cache 'default' is not enabled, check it was initialised"); } @Test @@ -1007,7 +1008,7 @@ public void shouldNotThrowExceptionWhenInitialisedWithNoCacheClassInProperties() @Test public void shouldAddGraphsToCache() throws Exception { - federatedProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); store.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, federatedProperties); // Given @@ -1027,19 +1028,19 @@ public void shouldAddGraphsToCache() throws Exception { final Collection storeGraphs = store.getGraphs(blankUser, null, new GetAllGraphIds()); // Then - assertThat(CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1); + assertThat(CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1); assertThat(storeGraphs).contains(graphToAdd); // When store = new FederatedStore(); // Then - assertThat(CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1); + assertThat(CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1); } @Test public void shouldAddMultipleGraphsToCache() throws Exception { - federatedProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); store.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, federatedProperties); // Given @@ -1057,7 +1058,7 @@ public void shouldAddMultipleGraphsToCache() throws Exception { // Then for (int i = 0; i < 10; i++) { - assertThat(CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1 + i); + assertThat(CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1 + i); } // When @@ -1065,7 +1066,7 @@ public void shouldAddMultipleGraphsToCache() throws Exception { // Then for (int i = 0; i < 10; i++) { - assertThat(CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1 + i); + assertThat(CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1 + i); } } @@ -1090,8 +1091,8 @@ public void shouldAddAGraphRemoveAGraphAndBeAbleToReuseTheGraphId() throws Excep public void shouldNotAddGraphToLibraryWhenReinitialisingFederatedStoreWithGraphFromCache() throws Exception { // Check cache is empty CacheServiceLoader.shutdown(); - federatedProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); - assertThat(CacheServiceLoader.getService()).isNull(); + federatedProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + assertThat(CacheServiceLoader.getDefaultService()).isNull(); // initialise FedStore store.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, federatedProperties); @@ -1108,7 +1109,7 @@ public void shouldNotAddGraphToLibraryWhenReinitialisingFederatedStoreWithGraphF // check is in the store assertThat(store.getAllGraphIds(blankUser)).hasSize(1); // check is in the cache - assertThat(CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1); + assertThat(CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME)).contains(ACC_ID_1); // check isn't in the LIBRARY assertThat(store.getGraphLibrary().get(ACC_ID_1)).isNull(); @@ -1120,8 +1121,8 @@ public void shouldNotAddGraphToLibraryWhenReinitialisingFederatedStoreWithGraphF store.setGraphLibrary(library); // check is in the cache still - assertThat(CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME)) - .withFailMessage(String.format("Keys: %s did not contain %s", CacheServiceLoader.getService().getAllKeysFromCache(CACHE_SERVICE_NAME), ACC_ID_1)).contains(ACC_ID_1); + assertThat(CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME)) + .withFailMessage(String.format("Keys: %s did not contain %s", CacheServiceLoader.getDefaultService().getAllKeysFromCache(CACHE_SERVICE_NAME), ACC_ID_1)).contains(ACC_ID_1); // check is in the store from the cache assertThat(store.getAllGraphIds(blankUser)).hasSize(1); // check the graph isn't in the GraphLibrary diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTestUtil.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTestUtil.java index 979bc472eb3..cd4f56a4818 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTestUtil.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTestUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 Crown Copyright + * Copyright 2022-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,6 +76,7 @@ public final class FederatedStoreTestUtil { public static final String GRAPH_ID_B = "graphB"; public static final String GRAPH_ID_C = "graphC"; public static final String FEDERATED_STORE_SINGLE_USE_PROPERTIES = "properties/singleUseFederatedStore.properties"; + public static final String FEDERATED_STORE_WITH_CACHE_PROPERTIES = "properties/federatedStore.properties"; public static final String SCHEMA_EDGE_BASIC_JSON = "/schema/basicEdgeSchema.json"; public static final String SCHEMA_ENTITY_BASIC_JSON = "/schema/basicEntitySchema.json"; public static final String SCHEMA_ENTITY_A_JSON = "/schema/entityASchema.json"; @@ -128,6 +129,10 @@ public static AccumuloProperties loadAccumuloStoreProperties(final String path) return AccumuloProperties.loadStoreProperties(path); } + public static FederatedStoreProperties getFederatedStorePropertiesWithHashMapCache() { + return loadFederatedStoreProperties(FEDERATED_STORE_WITH_CACHE_PROPERTIES); + } + public static void addGraphToAccumuloStore(final FederatedStore federatedStore, final String graphId, final boolean isPublic, final Schema schema) throws StorageException, OperationException { diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreToFederatedStoreTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreToFederatedStoreTest.java index 5353a07f882..56365ecc1fc 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreToFederatedStoreTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreToFederatedStoreTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 Crown Copyright + * Copyright 2020-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,7 @@ import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.SCHEMA_ENTITY_BASIC_JSON; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.edgeBasic; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.entityBasic; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.getFederatedStorePropertiesWithHashMapCache; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.loadSchemaFromJson; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.resetForFederatedTests; import static uk.gov.gchq.gaffer.proxystore.SingleUseProxyStore.CONTEXT_ROOT_SINGLE_USE_PROXY; @@ -82,7 +83,7 @@ public void setUpStores() throws OperationException { federatedStoreGraph = new Graph.Builder() .config(new GraphConfig("federatedStoreGraph")) - .storeProperties(new FederatedStoreProperties()) + .storeProperties(getFederatedStorePropertiesWithHashMapCache()) .build(); connectGraphs(); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreVisibilityTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreVisibilityTest.java index fb17e7d6231..9e84432e738 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreVisibilityTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreVisibilityTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 Crown Copyright + * Copyright 2022-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,7 +69,7 @@ public static void tearDownCache() { public void setUp() throws Exception { resetForFederatedTests(); FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); federatedGraph = new Graph.Builder() .config(new GraphConfig.Builder() diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreWrongGraphIDsTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreWrongGraphIDsTest.java index 8dcc97c8ea2..cb81677f01d 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreWrongGraphIDsTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreWrongGraphIDsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static uk.gov.gchq.gaffer.federatedstore.FederatedGraphStorage.GRAPH_IDS_NOT_VISIBLE; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.ACCUMULO_STORE_SINGLE_USE_PROPERTIES; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.CACHE_SERVICE_CLASS_STRING; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GRAPH_ID_ACCUMULO; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GRAPH_ID_TEST_FEDERATED_STORE; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GROUP_BASIC_ENTITY; @@ -56,7 +57,6 @@ public class FederatedStoreWrongGraphIDsTest { public static final String THERE_SHOULD_BE_ONE_ELEMENT = "There should be one expected element"; public static final String INTEGER = "Integer"; public static final String WRONG_GRAPH_ID = "x"; - private static final String CACHE_SERVICE_CLASS_STRING = "uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"; private FederatedStore federatedStore; @AfterAll @@ -71,7 +71,7 @@ public void setUp() throws Exception { federatedStore = new FederatedStore(); FederatedStoreProperties fedProps = new FederatedStoreProperties(); - fedProps.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + fedProps.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); federatedStore.initialise(GRAPH_ID_TEST_FEDERATED_STORE, null, fedProps); } diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/integration/FederatedStoreFileGraphLibraryIT.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/integration/FederatedStoreFileGraphLibraryIT.java index c43944cb88f..da6e24633f6 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/integration/FederatedStoreFileGraphLibraryIT.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/integration/FederatedStoreFileGraphLibraryIT.java @@ -42,6 +42,7 @@ import java.nio.file.Paths; import static org.assertj.core.api.Assertions.assertThat; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.CACHE_SERVICE_CLASS_STRING; /** * This test was created for gh-3129 and ensures the dynamic schema @@ -129,7 +130,7 @@ void shouldBeAbleToRecreateFederatedStoreWhenSchemaDeleted() throws IOException, static Graph getFederatedGraphUsingFileGraphLibrary() { FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); federatedStoreProperties.set(HashMapCacheService.STATIC_CACHE, String.valueOf(true)); - federatedStoreProperties.setCacheServiceClass("uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); FileGraphLibrary fileGraphLibrary = new FileGraphLibrary(libraryPath.toString()); return new Graph.Builder() .config(new GraphConfig.Builder() diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedAddGraphHandlerTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedAddGraphHandlerTest.java index 60d9d898773..a27914e8439 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedAddGraphHandlerTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedAddGraphHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,7 +83,7 @@ public void setUp() throws Exception { CacheServiceLoader.shutdown(); this.store = new FederatedStore(); federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); testUser = testUser(); authUser = authUser(); @@ -397,7 +397,7 @@ public void shouldAddGraphWithACache() throws StoreException, OperationException final FederatedAddGraphHandler federatedAddGraphHandler = new FederatedAddGraphHandler(); final AccumuloProperties properties = new AccumuloProperties(); properties.setProperties(PROPERTIES.getProperties()); - properties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + properties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); federatedAddGraphHandler.doOperation( new AddGraph.Builder() diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedAddGraphWithHooksHandlerTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedAddGraphWithHooksHandlerTest.java index b208fb13f4e..6000ccb0c7b 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedAddGraphWithHooksHandlerTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedAddGraphWithHooksHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +55,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static uk.gov.gchq.gaffer.federatedstore.FederatedGraphStorage.USER_IS_ATTEMPTING_TO_OVERWRITE; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.CACHE_SERVICE_CLASS_STRING; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.SCHEMA_EDGE_BASIC_JSON; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.loadSchemaFromJson; import static uk.gov.gchq.gaffer.user.StoreUser.authUser; @@ -66,7 +67,6 @@ public class FederatedAddGraphWithHooksHandlerTest { private static final String EXPECTED_GRAPH_ID = "testGraphID"; private static final String EXPECTED_GRAPH_ID_2 = "testGraphID2"; private static final String EXPECTED_GRAPH_ID_3 = "testGraphID3"; - private static final String CACHE_SERVICE_CLASS_STRING = "uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"; private User testUser; private User authUser; private User blankUser; @@ -80,7 +80,7 @@ public void setUp() throws Exception { CacheServiceLoader.shutdown(); this.store = new FederatedStore(); federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); testUser = testUser(); authUser = authUser(); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedGetTraitsHandlerTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedGetTraitsHandlerTest.java index ed96af3dcce..a8fcb5333f3 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedGetTraitsHandlerTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedGetTraitsHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 Crown Copyright + * Copyright 2018-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import uk.gov.gchq.gaffer.accumulostore.AccumuloProperties; import uk.gov.gchq.gaffer.cache.CacheServiceLoader; -import uk.gov.gchq.gaffer.commonutil.StreamUtil; import uk.gov.gchq.gaffer.data.element.Element; import uk.gov.gchq.gaffer.data.element.id.EntityId; import uk.gov.gchq.gaffer.federatedstore.FederatedStore; @@ -50,6 +49,9 @@ import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.ACCUMULO_STORE_SINGLE_USE_PROPERTIES; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.getFederatedStorePropertiesWithHashMapCache; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.loadAccumuloStoreProperties; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getFederatedOperation; import static uk.gov.gchq.gaffer.store.StoreTrait.MATCHED_VERTEX; import static uk.gov.gchq.gaffer.store.StoreTrait.POST_AGGREGATION_FILTERING; @@ -62,15 +64,14 @@ public class FederatedGetTraitsHandlerTest { public static final String ALT_STORE = "altStore"; public static final String FED_STORE_ID = "fedStoreId"; public static final String ACC_STORE = "accStore"; - private static final AccumuloProperties PROPERTIES = AccumuloProperties.loadStoreProperties(StreamUtil.openStream(FederatedGetTraitsHandlerTest.class, "/properties/singleUseAccumuloStore.properties")); + private static final AccumuloProperties ACCUMULO_PROPERTIES = loadAccumuloStoreProperties(ACCUMULO_STORE_SINGLE_USE_PROPERTIES); private StoreProperties storeProperties; private FederatedStore federatedStore; - private FederatedStoreProperties properties; + private static final FederatedStoreProperties FEDERATED_STORE_PROPERTIES = getFederatedStorePropertiesWithHashMapCache(); @BeforeEach public void setUp() throws Exception { federatedStore = new FederatedStore(); - properties = new FederatedStoreProperties(); HashMapGraphLibrary.clear(); CacheServiceLoader.shutdown(); storeProperties = new StoreProperties(); @@ -86,7 +87,7 @@ void afterEach() { @Test public void shouldGetZeroTraitsForEmptyStore() throws Exception { // Given - federatedStore.initialise(FED_STORE_ID, null, properties); + federatedStore.initialise(FED_STORE_ID, null, FEDERATED_STORE_PROPERTIES); // When final Set traits = federatedStore.execute( @@ -102,7 +103,7 @@ public void shouldGetZeroTraitsForEmptyStore() throws Exception { @Test public void shouldGetNullTraitsForEmptyStoreWithCurrentTraits() throws Exception { // Given - federatedStore.initialise(FED_STORE_ID, null, properties); + federatedStore.initialise(FED_STORE_ID, null, FEDERATED_STORE_PROPERTIES); assertThat(federatedStore.getAllGraphIds(testUser())).withFailMessage("graph is not starting empty").isEmpty(); // When @@ -117,7 +118,7 @@ public void shouldGetNullTraitsForEmptyStoreWithCurrentTraits() throws Exception @Test public void shouldGetAllTraitsWhenContainsStoreWithOtherTraits() throws Exception { // Given - federatedStore.initialise(FED_STORE_ID, null, properties); + federatedStore.initialise(FED_STORE_ID, null, FEDERATED_STORE_PROPERTIES); federatedStore.execute(new AddGraph.Builder() .isPublic(true) .graphId(ALT_STORE) @@ -153,7 +154,7 @@ public void shouldGetAllTraitsWhenContainsStoreWithOtherTraits() throws Exceptio @Test public void shouldGetCurrentTraitsWhenContainsStoreWithOtherTraits() throws Exception { // Given - federatedStore.initialise(FED_STORE_ID, null, properties); + federatedStore.initialise(FED_STORE_ID, null, FEDERATED_STORE_PROPERTIES); federatedStore.execute(new AddGraph.Builder() .isPublic(true) .graphId(ALT_STORE) @@ -180,7 +181,7 @@ public void shouldGetCurrentTraitsWhenContainsStoreWithOtherTraits() throws Exce @Test public void shouldGetCurrentTraitsWhenContainsStoreWithOtherTraitsWithOptions() throws Exception { // Given - federatedStore.initialise(FED_STORE_ID, null, properties); + federatedStore.initialise(FED_STORE_ID, null, FEDERATED_STORE_PROPERTIES); federatedStore.execute(new AddGraph.Builder() .isPublic(true) @@ -192,7 +193,7 @@ public void shouldGetCurrentTraitsWhenContainsStoreWithOtherTraitsWithOptions() federatedStore.execute(new AddGraph.Builder() .isPublic(true) .graphId(ACC_STORE) - .storeProperties(PROPERTIES) + .storeProperties(ACCUMULO_PROPERTIES) .schema(new Schema()) .build(), new Context(testUser())); @@ -217,7 +218,7 @@ public void shouldGetCurrentTraitsWhenContainsStoreWithOtherTraitsWithOptions() @Test public void shouldGetAllTraitsWhenContainsStoreWithOtherTraitsWithOptions() throws Exception { // Given - federatedStore.initialise(FED_STORE_ID, null, properties); + federatedStore.initialise(FED_STORE_ID, null, FEDERATED_STORE_PROPERTIES); federatedStore.execute(new AddGraph.Builder() .isPublic(true) @@ -229,7 +230,7 @@ public void shouldGetAllTraitsWhenContainsStoreWithOtherTraitsWithOptions() thro federatedStore.execute(new AddGraph.Builder() .isPublic(true) .graphId(ACC_STORE) - .storeProperties(PROPERTIES) + .storeProperties(ACCUMULO_PROPERTIES) .schema(new Schema()) .build(), new Context(testUser())); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedOperationChainHandlerTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedOperationChainHandlerTest.java index c614dc903ac..adbbb6e1624 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedOperationChainHandlerTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedOperationChainHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 Crown Copyright + * Copyright 2016-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,14 +21,12 @@ import org.junit.jupiter.api.Test; import uk.gov.gchq.gaffer.cache.CacheServiceLoader; -import uk.gov.gchq.gaffer.commonutil.StreamUtil; import uk.gov.gchq.gaffer.commonutil.TestGroups; import uk.gov.gchq.gaffer.data.element.Edge; import uk.gov.gchq.gaffer.data.element.Element; import uk.gov.gchq.gaffer.data.element.Entity; import uk.gov.gchq.gaffer.data.util.ElementUtil; import uk.gov.gchq.gaffer.federatedstore.FederatedStore; -import uk.gov.gchq.gaffer.federatedstore.integration.FederatedStoreITs; import uk.gov.gchq.gaffer.federatedstore.operation.FederatedOperation; import uk.gov.gchq.gaffer.operation.OperationChain; import uk.gov.gchq.gaffer.operation.OperationException; @@ -38,7 +36,6 @@ import uk.gov.gchq.gaffer.operation.impl.get.GetAllElements; import uk.gov.gchq.gaffer.store.Context; import uk.gov.gchq.gaffer.store.Store; -import uk.gov.gchq.gaffer.store.StoreProperties; import uk.gov.gchq.gaffer.store.TestTypes; import uk.gov.gchq.gaffer.store.library.HashMapGraphLibrary; import uk.gov.gchq.gaffer.store.schema.Schema; @@ -55,6 +52,7 @@ import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GRAPH_ID_ACCUMULO_WITH_EDGES; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GRAPH_ID_ACCUMULO_WITH_ENTITIES; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GRAPH_ID_TEST_FEDERATED_STORE; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.loadFederatedStoreProperties; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getDefaultMergeFunction; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getFederatedOperation; @@ -252,7 +250,7 @@ private FederatedStore createStore() throws OperationException { .validateFunctions(new IsTrue()) .build()) .build(); - final FederatedStore store = (FederatedStore) Store.createStore(GRAPH_ID_TEST_FEDERATED_STORE, schema, StoreProperties.loadStoreProperties(StreamUtil.openStream(FederatedStoreITs.class, "predefinedFederatedStore.properties"))); + final FederatedStore store = (FederatedStore) Store.createStore(GRAPH_ID_TEST_FEDERATED_STORE, schema, loadFederatedStoreProperties("predefinedFederatedStore.properties")); final Context context = new Context(); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedRemoveGraphHandlerTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedRemoveGraphHandlerTest.java index a8ad3fceae1..1528e683754 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedRemoveGraphHandlerTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedRemoveGraphHandlerTest.java @@ -24,7 +24,6 @@ import uk.gov.gchq.gaffer.accumulostore.AccumuloProperties; import uk.gov.gchq.gaffer.cache.CacheServiceLoader; import uk.gov.gchq.gaffer.cache.ICache; -import uk.gov.gchq.gaffer.commonutil.StreamUtil; import uk.gov.gchq.gaffer.data.elementdefinition.view.View; import uk.gov.gchq.gaffer.data.elementdefinition.view.ViewElementDefinition; import uk.gov.gchq.gaffer.federatedstore.FederatedStore; @@ -45,21 +44,22 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.ACCUMULO_STORE_SINGLE_USE_PROPERTIES; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.CACHE_SERVICE_CLASS_STRING; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GROUP_BASIC_ENTITY; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.PROPERTY_1; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.basicEntitySchema; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.contextTestUser; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.getFederatedStorePropertiesWithHashMapCache; +import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.loadAccumuloStoreProperties; import static uk.gov.gchq.gaffer.user.StoreUser.testUser; public class FederatedRemoveGraphHandlerTest { private static final String FEDERATEDSTORE_GRAPH_ID = "federatedStore"; private static final String EXPECTED_GRAPH_ID = "testGraphID"; - private static final String CACHE_SERVICE_CLASS_STRING = "uk.gov.gchq.gaffer.cache.impl.HashMapCacheService"; private User testUser; - private static Class currentClass = new Object() { - }.getClass().getEnclosingClass(); - private static final AccumuloProperties PROPERTIES = AccumuloProperties.loadStoreProperties(StreamUtil.openStream(currentClass, "properties/singleUseAccumuloStore.properties")); + private static final AccumuloProperties PROPERTIES = loadAccumuloStoreProperties(ACCUMULO_STORE_SINGLE_USE_PROPERTIES); @BeforeEach public void setUp() throws Exception { @@ -70,10 +70,7 @@ public void setUp() throws Exception { @Test public void shouldRemoveGraphForOwningUser() throws Exception { FederatedStore store = new FederatedStore(); - final FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); - - store.initialise(FEDERATEDSTORE_GRAPH_ID, null, federatedStoreProperties); + store.initialise(FEDERATEDSTORE_GRAPH_ID, null, getFederatedStorePropertiesWithHashMapCache()); store.addGraphs(testUser.getOpAuths(), testUser.getUserId(), false, new GraphSerialisable.Builder() .config(new GraphConfig(EXPECTED_GRAPH_ID)) @@ -99,10 +96,7 @@ public void shouldRemoveGraphForOwningUser() throws Exception { @Test public void shouldNotRemoveGraphForNonOwningUser() throws Exception { FederatedStore store = new FederatedStore(); - final FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); - - store.initialise(FEDERATEDSTORE_GRAPH_ID, null, federatedStoreProperties); + store.initialise(FEDERATEDSTORE_GRAPH_ID, null, getFederatedStorePropertiesWithHashMapCache()); store.addGraphs(testUser.getOpAuths(), "other", false, new GraphSerialisable.Builder() .config(new GraphConfig(EXPECTED_GRAPH_ID)) @@ -128,10 +122,7 @@ public void shouldNotRemoveGraphForNonOwningUser() throws Exception { @Test public void shouldReturnFalseWhenNoGraphWasRemoved() throws Exception { FederatedStore store = new FederatedStore(); - final FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); - - store.initialise(FEDERATEDSTORE_GRAPH_ID, null, federatedStoreProperties); + store.initialise(FEDERATEDSTORE_GRAPH_ID, null, getFederatedStorePropertiesWithHashMapCache()); assertEquals(0, store.getGraphs(testUser, null, new RemoveGraph()).size()); @@ -152,10 +143,7 @@ public void shouldReturnFalseWhenNoGraphWasRemoved() throws Exception { @Test public void shouldNotRemoveGraphConfiguredWithNoAccessWritePredicate() throws Exception { FederatedStore store = new FederatedStore(); - final FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); - - store.initialise(FEDERATEDSTORE_GRAPH_ID, null, federatedStoreProperties); + store.initialise(FEDERATEDSTORE_GRAPH_ID, null, getFederatedStorePropertiesWithHashMapCache()); final AccessPredicate noAccessPredicate = new NoAccessPredicate(); @@ -188,22 +176,19 @@ public void shouldNotRemoveGraphConfiguredWithNoAccessWritePredicate() throws Ex @Test public void shouldRemoveGraphButNotCache() throws Exception { FederatedStore store = new FederatedStore(); - final FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); - - store.initialise(FEDERATEDSTORE_GRAPH_ID, null, federatedStoreProperties); + store.initialise(FEDERATEDSTORE_GRAPH_ID, null, getFederatedStorePropertiesWithHashMapCache()); final String removeThisCache = "removeThisCache"; final String myViewToRemove = "myViewToRemove"; - final ICache cache = CacheServiceLoader.getService().getCache(NamedViewCache.getCacheNameFrom(removeThisCache)); + final ICache cache = CacheServiceLoader.getDefaultService().getCache(NamedViewCache.getCacheNameFrom(removeThisCache)); assertThat(cache).isNotNull(); assertThat(cache.get(myViewToRemove)).isNull(); assertThat(cache.size()).isZero(); final AccumuloProperties clone = PROPERTIES.clone(); - clone.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + clone.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); clone.setCacheServiceNameSuffix(removeThisCache); store.execute(new AddGraph.Builder() @@ -238,21 +223,18 @@ public void shouldRemoveGraphButNotCache() throws Exception { @Test public void shouldRemoveGraphAndCache() throws Exception { FederatedStore store = new FederatedStore(); - final FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); - - store.initialise(FEDERATEDSTORE_GRAPH_ID, null, federatedStoreProperties); + store.initialise(FEDERATEDSTORE_GRAPH_ID, null, getFederatedStorePropertiesWithHashMapCache()); final String removeThisCache = "removeThisCache"; final String myViewToRemove = "myViewToRemove"; - final ICache cache = CacheServiceLoader.getService().getCache(NamedViewCache.getCacheNameFrom(removeThisCache)); + final ICache cache = CacheServiceLoader.getDefaultService().getCache(NamedViewCache.getCacheNameFrom(removeThisCache)); assertThat(cache).isNotNull(); assertThat(cache.get(myViewToRemove)).isNull(); assertThat(cache.size()).isZero(); final AccumuloProperties clone = PROPERTIES.clone(); - clone.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + clone.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); clone.setCacheServiceNameSuffix(removeThisCache); store.execute(new AddGraph.Builder() @@ -283,4 +265,70 @@ public void shouldRemoveGraphAndCache() throws Exception { assertThat(graphs).isEmpty(); } + + @Test + public void shouldRemoveGraphAndCacheWhenUsingMultipleServices() throws Exception { + // Create and initialise a new Federated Store with the default cache service class store property configured + FederatedStore store = new FederatedStore(); + final FederatedStoreProperties federatedStoreProperties = new FederatedStoreProperties(); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + store.initialise(FEDERATEDSTORE_GRAPH_ID, null, federatedStoreProperties); + + final String cacheNameSuffix = "removeThisCache"; + final String viewName = "myViewToRemove"; + + // Get default cache (initialised by the Federated Store) and check any cache entry for the view is empty + final ICache defaultCache = CacheServiceLoader.getDefaultService().getCache(NamedViewCache.getCacheNameFrom(cacheNameSuffix)); + assertThat(defaultCache).isNotNull(); + assertThat(defaultCache.size()).isZero(); + + // Set Accumulo Store properties to use separate cache instances/services for Named Views and set suffix + final AccumuloProperties accumuloProperties = PROPERTIES.clone(); + accumuloProperties.setNamedViewCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + accumuloProperties.setCacheServiceNameSuffix(cacheNameSuffix); + + // Add graph to the Federated Store using the Accumulo Store properties + store.execute(new AddGraph.Builder() + .graphId(EXPECTED_GRAPH_ID) + .schema(basicEntitySchema()) + .isPublic(true) + .storeProperties(accumuloProperties) + .build(), contextTestUser()); + + // Get NamedView specific cache and check any cache entry for the view is empty + final ICache namedViewSpecificCache = CacheServiceLoader.getService(NamedViewCache.NAMED_VIEW_CACHE_SERVICE_NAME).getCache(NamedViewCache.getCacheNameFrom(cacheNameSuffix)); + assertThat(namedViewSpecificCache).isNotNull(); + assertThat(namedViewSpecificCache.size()).isZero(); + + // Add a view to the new Accumulo backed graph + store.execute(new FederatedOperation.Builder().op(new AddNamedView.Builder().name(viewName).view(new View.Builder().edge(GROUP_BASIC_ENTITY, new ViewElementDefinition.Builder().properties(PROPERTY_1).build()).build()).build()).build(), contextTestUser()); + + // Check that cache entry for the view is present in the NamedView specific cache + assertThat(namedViewSpecificCache.size()).isEqualTo(1); + assertThat(namedViewSpecificCache.get(viewName)).isNotNull(); + + // Check there is no cache entry for the view in the default cache + assertThat(defaultCache).isNotNull(); + assertThat(defaultCache.size()).isZero(); + + // Check there is a graph present in the Federated Store + assertThat(store.getGraphs(testUser, null, new RemoveGraph())).hasSize(1); + + // Remove the Accumulo backed graph from the Federated Store + new FederatedRemoveGraphHandler().doOperation( + new RemoveGraph.Builder() + .graphId(EXPECTED_GRAPH_ID) + //.removeCache(true) User default value + .build(), + new Context(testUser), + store); + + // Check that the cache entry for the view has been removed from the NamedView specific cache + assertThat(namedViewSpecificCache.size()).isZero(); + assertThat(namedViewSpecificCache.get(viewName)).isNull(); + + // Check that graph has been removed from the Federated Store + Collection graphs = store.getGraphs(testUser, null, new RemoveGraph()); + assertThat(graphs).isEmpty(); + } } diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedUnhandledOperationTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedUnhandledOperationTest.java index 562e44fe641..c8c43750d2c 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedUnhandledOperationTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedUnhandledOperationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Crown Copyright + * Copyright 2022-2024 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ public class FederatedUnhandledOperationTest { public void setUp() throws Exception { FederatedStoreTestUtil.resetForFederatedTests(); federatedStoreProperties = new FederatedStoreProperties(); - federatedStoreProperties.setCacheServiceClass(CACHE_SERVICE_CLASS_STRING); + federatedStoreProperties.setDefaultCacheServiceClass(CACHE_SERVICE_CLASS_STRING); } @AfterEach diff --git a/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIds.properties b/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIds.properties index 2d9fe9fcd9b..c6631a3cc7d 100644 --- a/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIds.properties +++ b/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIds.properties @@ -15,5 +15,5 @@ # gaffer.store.class=uk.gov.gchq.gaffer.federatedstore.FederatedStore gaffer.store.properties.class=uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService gaffer.federatedstore.storeConfiguredGraphIds=configuredProperties/configuredGraphIds.json diff --git a/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIdsFailFileInvalid.properties b/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIdsFailFileInvalid.properties index df523dac3c8..23bcb5143d1 100644 --- a/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIdsFailFileInvalid.properties +++ b/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIdsFailFileInvalid.properties @@ -15,5 +15,5 @@ # gaffer.store.class=uk.gov.gchq.gaffer.federatedstore.FederatedStore gaffer.store.properties.class=uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService gaffer.federatedstore.storeConfiguredGraphIds=configuredProperties/configuredGraphIdsFileInvalid.json diff --git a/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIdsFailPathMissing.properties b/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIdsFailPathMissing.properties index 041f9e09187..89493a1d735 100644 --- a/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIdsFailPathMissing.properties +++ b/store-implementation/federated-store/src/test/resources/configuredProperties/federatedStoreConfiguredGraphIdsFailPathMissing.properties @@ -15,5 +15,5 @@ # gaffer.store.class=uk.gov.gchq.gaffer.federatedstore.FederatedStore gaffer.store.properties.class=uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService gaffer.federatedstore.storeConfiguredGraphIds=fail diff --git a/store-implementation/federated-store/src/test/resources/integrationTestPublicAccessPredefinedFederatedStore.properties b/store-implementation/federated-store/src/test/resources/integrationTestPublicAccessPredefinedFederatedStore.properties index 4c27edf1f5e..69051d839c8 100644 --- a/store-implementation/federated-store/src/test/resources/integrationTestPublicAccessPredefinedFederatedStore.properties +++ b/store-implementation/federated-store/src/test/resources/integrationTestPublicAccessPredefinedFederatedStore.properties @@ -14,7 +14,7 @@ # limitations under the License. # gaffer.store.class=uk.gov.gchq.gaffer.federatedstore.PublicAccessPredefinedFederatedStore -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService gaffer.store.admin.auth=AdminAuth gaffer.federatedstore.storeConfiguredMergeFunctions=integrationTestMergeFunctions.json diff --git a/store-implementation/federated-store/src/test/resources/predefinedFederatedStore.properties b/store-implementation/federated-store/src/test/resources/predefinedFederatedStore.properties index 28dde84ed82..ff5c94846db 100644 --- a/store-implementation/federated-store/src/test/resources/predefinedFederatedStore.properties +++ b/store-implementation/federated-store/src/test/resources/predefinedFederatedStore.properties @@ -14,4 +14,4 @@ # limitations under the License. # gaffer.store.class=uk.gov.gchq.gaffer.federatedstore.PredefinedFederatedStore -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService diff --git a/store-implementation/federated-store/src/test/resources/properties/federatedStore.properties b/store-implementation/federated-store/src/test/resources/properties/federatedStore.properties new file mode 100644 index 00000000000..47095ab0d10 --- /dev/null +++ b/store-implementation/federated-store/src/test/resources/properties/federatedStore.properties @@ -0,0 +1,18 @@ +# +# Copyright 2017-2024 Crown Copyright +# +# 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. +# +gaffer.store.class=uk.gov.gchq.gaffer.federatedstore.FederatedStore +gaffer.store.properties.class=uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService diff --git a/store-implementation/federated-store/src/test/resources/publicAccessPredefinedFederatedStore.properties b/store-implementation/federated-store/src/test/resources/publicAccessPredefinedFederatedStore.properties index 422bb0bde19..1c020ce00f3 100644 --- a/store-implementation/federated-store/src/test/resources/publicAccessPredefinedFederatedStore.properties +++ b/store-implementation/federated-store/src/test/resources/publicAccessPredefinedFederatedStore.properties @@ -14,5 +14,5 @@ # limitations under the License. # gaffer.store.class=uk.gov.gchq.gaffer.federatedstore.PublicAccessPredefinedFederatedStore -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService gaffer.store.admin.auth=AdminAuth diff --git a/store-implementation/map-store/src/test/resources/store.properties b/store-implementation/map-store/src/test/resources/store.properties index 7fbb5123197..0d14a0a61fe 100755 --- a/store-implementation/map-store/src/test/resources/store.properties +++ b/store-implementation/map-store/src/test/resources/store.properties @@ -16,5 +16,5 @@ gaffer.store.class=uk.gov.gchq.gaffer.mapstore.SingleUseMapStore # Use a small buffer size to test adding in batches gaffer.store.mapstore.map.ingest.buffer.size=5 -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService gaffer.store.job.tracker.enabled=true diff --git a/store-implementation/proxy-store/src/test/resources/map-store.properties b/store-implementation/proxy-store/src/test/resources/map-store.properties index 54f76be6df7..4262325e390 100755 --- a/store-implementation/proxy-store/src/test/resources/map-store.properties +++ b/store-implementation/proxy-store/src/test/resources/map-store.properties @@ -16,4 +16,4 @@ gaffer.store.class=uk.gov.gchq.gaffer.mapstore.SingleUseMapStoreWithoutVisibilitySupport gaffer.store.properties.class=uk.gov.gchq.gaffer.mapstore.MapStoreProperties gaffer.store.job.tracker.enabled=true -gaffer.cache.service.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService +gaffer.cache.service.default.class=uk.gov.gchq.gaffer.cache.impl.HashMapCacheService