Skip to content
Snippets Groups Projects

Fix issue with cache param map leaks, add fuzzy remove tests

Merged Martin Lowe requested to merge malowe/eclipsefdn-api-common:malowe/main/0.8.0 into main
2 files
+ 98
9
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -53,7 +53,7 @@ import io.quarkus.cache.CaffeineCache;
@@ -53,7 +53,7 @@ import io.quarkus.cache.CaffeineCache;
@ApplicationScoped
@ApplicationScoped
public class QuarkusCachingService implements CachingService {
public class QuarkusCachingService implements CachingService {
private static final Logger LOGGER = LoggerFactory.getLogger(QuarkusCachingService.class);
private static final Logger LOGGER = LoggerFactory.getLogger(QuarkusCachingService.class);
@ConfigProperty(name = MicroprofilePropertyNames.CACHE_TTL_MAX_SECONDS, defaultValue = "900")
@ConfigProperty(name = MicroprofilePropertyNames.CACHE_TTL_MAX_SECONDS, defaultValue = "900")
long ttlWrite;
long ttlWrite;
@@ -67,13 +67,8 @@ public class QuarkusCachingService implements CachingService {
@@ -67,13 +67,8 @@ public class QuarkusCachingService implements CachingService {
@Override
@Override
public <T> Optional<T> get(String id, MultivaluedMap<String, String> params, Class<?> rawType, Callable<? extends T> callable) {
public <T> Optional<T> get(String id, MultivaluedMap<String, String> params, Class<?> rawType, Callable<? extends T> callable) {
Objects.requireNonNull(callable);
Objects.requireNonNull(callable);
// create the cache key for the entry, cloning the map for key integrity
ParameterizedCacheKey cacheKey = ParameterizedCacheKey
ParameterizedCacheKey cacheKey = ParameterizedCacheKey.builder().setClazz(rawType).setId(id).setParams(cloneMap(params)).build();
.builder()
.setClazz(rawType)
.setId(id)
.setParams(params != null ? params : new MultivaluedMapImpl<>())
.build();
LOGGER.debug("Retrieving cache value for '{}'", cacheKey);
LOGGER.debug("Retrieving cache value for '{}'", cacheKey);
return Optional.ofNullable(get(cacheKey, callable));
return Optional.ofNullable(get(cacheKey, callable));
}
}
@@ -167,7 +162,7 @@ public class QuarkusCachingService implements CachingService {
@@ -167,7 +162,7 @@ public class QuarkusCachingService implements CachingService {
}
}
@CacheResult(cacheName = "default")
@CacheResult(cacheName = "default")
public <T> T get(@CacheKey ParameterizedCacheKey cacheKey, Callable<? extends T> callable) {
<T> T get(@CacheKey ParameterizedCacheKey cacheKey, Callable<? extends T> callable) {
// attempt to get the result for the cache entry
// attempt to get the result for the cache entry
T out = null;
T out = null;
try {
try {
@@ -189,4 +184,18 @@ public class QuarkusCachingService implements CachingService {
@@ -189,4 +184,18 @@ public class QuarkusCachingService implements CachingService {
return System.currentTimeMillis() + getMaxAge();
return System.currentTimeMillis() + getMaxAge();
}
}
 
/**
 
* To prevent modification of maps/cache key entries post retrieval, we should be referencing copies of the maps rather
 
* than the direct passed reference for safety.
 
*
 
* @return the copied map, or an empty map if null
 
*/
 
private MultivaluedMap<String, String> cloneMap(MultivaluedMap<String, String> paramMap) {
 
MultivaluedMap<String, String> out = new MultivaluedMapImpl<>();
 
if (paramMap != null) {
 
paramMap.entrySet().forEach(e -> out.addAll(e.getKey(), e.getValue()));
 
}
 
return out;
 
}
 
}
}
Loading