If service been hit after data is been expired. It is returning the old data and then refresing the data in the second hit. This is causing service to fail.
@Cacheable(value = "tokenCache", cacheManager = "springTokenCacheManager")
public String getToken(PublicKey publicKey) {....}
Jcache manager bean:
@Bean
public JCacheCacheManager springTokenCacheManager(
@Qualifier("tokenCacheManager") CacheManager cacheManager) {
return new JCacheCacheManager(cacheManager);
}
@Bean(destroyMethod = "close")
public CacheManager tokenCacheManager(
TokenExpiryPolicy tokenExpiryPolicy, CacheEventLogger cacheEventLogger) {
CacheEventListenerConfigurationBuilder cacheEventListenerConfiguration =
CacheEventListenerConfigurationBuilder.newEventListenerConfiguration(
cacheEventLogger,
EventType.CREATED,
EventType.UPDATED,
EventType.EVICTED,
EventType.EXPIRED,
EventType.REMOVED)
.unordered()
.asynchronous();
CacheConfiguration<PublicKey, String> cacheConfiguration =
CacheConfigurationBuilder.newCacheConfigurationBuilder(
PublicKey.class, String.class, ResourcePoolsBuilder.heap(1))
.withExpiry(tokenExpiryPolicy)
.withService(cacheEventListenerConfiguration)
.build();
EhcacheCachingProvider provider =
(EhcacheCachingProvider)
Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider");
CacheManager cacheManager = provider.getCacheManager();
Cache<PublicKey, String> cache =
cacheManager.createCache(
TOKEN_CACHE, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration));
return cacheManager;
}
ExpiryPolicy
@Component
public class TokenExpiryPolicy implements ExpiryPolicy<PublicKey, String> {
@Override
public Duration getExpiryForCreation(PublicKey key, String value) {
Duration expiryDate = getExpiryDate(value);
log.info("Token expires duration for creation {}", expiryDate);
return expiryDate;
}
@Override
public Duration getExpiryForAccess(PublicKey key, Supplier<? extends String> value) {
Duration expiryDate = getExpiryDate(value.get());
log.info("Token expires duration for access {}", expiryDate);
return expiryDate;
}
@Override
public Duration getExpiryForUpdate(
PublicKey key, Supplier<? extends String> oldValue, String newValue) {
Duration expiryDate = getExpiryDate(newValue);
log.info("Token expires duration for update {}", expiryDate);
return expiryDate;
}
private Duration getExpiryDate(String token) {
Duration expiry = Duration.ZERO;
try {
DecodedJWT decodedJWT = JWT.decode(token);
Date expiresAt = decodedJWT.getExpiresAt();
log.info("Token expires at {}", expiresAt);
Date currentDate = new Date();
if (expiresAt.before(currentDate)) {
log.info("Token expired {}", expiresAt);
} else {
expiry = Duration.ofMillis(expiresAt.getTime());
}
} catch (JWTDecodeException e) {
log.error("Exception while decoding JWT token");
}
return expiry;
}
}
Logs:
[2023-04-12 15:29:08,014 XNIO-1 task-2] INFO c.b.s.s.s.caching.TokenExpiryPolicy - Token expires at Wed Apr 12 13:30:26 BST 2023
[2023-04-12 15:29:08,014 XNIO-1 task-1] INFO c.b.s.s.s.caching.TokenExpiryPolicy - Token expires at Wed Apr 12 13:30:26 BST 2023
[2023-04-12 15:29:08,015 XNIO-1 task-1] INFO c.b.s.s.s.caching.TokenExpiryPolicy - Token expired Wed Apr 12 13:30:26 BST 2023
[2023-04-12 15:29:08,015 XNIO-1 task-2] INFO c.b.s.s.s.caching.TokenExpiryPolicy - Token expired Wed Apr 12 13:30:26 BST 2023
[2023-04-12 15:29:08,016 XNIO-1 task-1] INFO c.b.s.s.s.caching.TokenExpiryPolicy - Token expires duration for access PT0S
[2023-04-12 15:29:08,016 XNIO-1 task-2] INFO c.b.s.s.s.caching.TokenExpiryPolicy - Token expires duration for access PT0S
[2023-04-12 15:29:08,024 Ehcache [_default_]-4] INFO c.b.s.s.s.caching.CacheEventLogger - caching listener event: EXPIRED key: Sun RSA public key, 2048 bits
params: null
After this failed request, I see cache has been created again
[2023-04-12 15:32:18,726 Ehcache [default]-5] INFO c.b.s.s.s.caching.CacheEventLogger - caching listener event: CREATED key: Sun RSA public key, 2048 bits