ArnabSaha
ArnabSaha

Reputation: 29

@Cacheble and @Scheduled to start at same time in Spring boot application

Preface: The requirement in a product (a bunch of spring boot applications), I am working is to use JWT Tokens for security, fetched from an internal server, and use it to communicate amongst services via REST calls.

Problem: The JWT Token TTL is exact 2 hours, so I tried to put it in a cache, so that for a given userId, I should not fetch a new JWT Token from the server before it expires. This part works, the issue was to evict the cache when the TTL expires.

The code is as follows.

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Scheduled;

public class JWTUtility {

    // Some Fake JWT Ticket
    private static final String FAKE_JWT_TICKET = "";

    @Cacheable(value = "jwtToken", key = "#userId", condition = "#userId != null")
    public String getToken(boolean securityEnabled, String userId) {
        if (!securityEnabled) {
            return FAKE_JWT_TICKET;
        } else {
            // Proper logic to fetch and return the JWT token from Server
            // Assume this works
        }
    }

    // JWT Ticket TTL is 2 Hrs, scheduling cache evict at 1:50 Hrs
    @Scheduled(fixedRate = 6600000)
    @CacheEvict(value = "jwtToken", allEntries = true)
    public void evictJWTTicketValues() {
        //Intentionally left blank
    }
}

The scheduling part does not work as I was expecting it to. The question is how to start the timer of the scheduler as and when some JWT ticket for a particular userId enters the Cache jwtToken. I am open to refactoring/re-writing logic for the above JWTUtility class entirely.

Upvotes: 0

Views: 2656

Answers (1)

Pankaj
Pankaj

Reputation: 2678

As @Thomas Kåsene pointed out - if you can use other cache provider then you can set the eviction policy, while configuring the cache. Below is example for configuring Caffeine Cache :

@Bean
  public CaffeineCache jwtTokenCache() {
    return new CaffeineCache(
        "jwtTokenCache",
        Caffeine.newBuilder().expireAfterWrite(120, TimeUnit.MINUTES).recordStats().build());
  }

You need to declare annotate your method as -

@Cacheable(cacheNames = "jwtTokenCache", value = "jwtToken", key = "#userId", condition = "#userId != null")

Upvotes: 1

Related Questions