0

I am using springBootVersion = 1.5.2.RELEASE and gradle version = 5.4.1.

I am passing token(consider an account) in request, There might be multiple channels associated to an account(requested token), I want to fetch all channels associated to request account and store them into List.

If user not perform any activity for 2 minutes for that user only Cache should be expired.

In order to fetch channelIds and store them into List, I have used Spring boot @Cacheable annotation but It is not working expected as it is fetching existing list data.

Please consider a dummy scenario to understand.

If I request token = 123, API fetching all channels associated this token and storing them into list which is fine.

but when I request token = 987 still API returning token = 123 channels, API supposed to return channels associated to token = 987

Here is code snippet

Main Spring Boot Runner Class

@SpringBootApplication
@EnableCaching
@ComponentScan(basePackages = { "some packages to scan" })
public class ChannelApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(ChannelApiApplication.class, args);
    }
}

UserController.java

@RestController
public class UserController {
public ResponseEntity<AccountsAssociatedChannels> getAccountsAssociatedChannels(
        @PathVariable Integer userId,
        @RequestHeader("Cookie") String btCookie,
        @RequestParam(value = "page", required = false, defaultValue = "1") int page,
        @RequestParam(value = "pageSize", required = false, defaultValue = "25") int pageSize,
        UriComponentsBuilder uriBuilder, HttpServletResponse response, HttpServletRequest request)
        throws Exception {
    try {
        List<AccountAssociatedChannels> accountResponse = userService.getAccountsAssociatedChannels(userId,
                btCookie, page, pageSize);

UserService.java

@Service
@Configurable
public class UserService {

@Autowired
ChannelServiceClient channelServiceClient;

public List<AccountAssociatedChannels> getAccountsAssociatedChannels(Integer userId, String btCookie, int page,
            int pageSize) throws Exception {

    // Calling Rest API to get channels associated to btCookie
    List<MyChannelResponse> myChannelResponse = channelServiceClient.getMyChannelResponse(btCookie, page,
            pageSize, null);

ChannelServiceClient.java

@Service
public class ChannelServiceClient {

    @Cacheable(value = "channelIds", key = "#root.args[0]")
    public List<MyChannelResponse> getMyChannelResponse(String btCookie, Integer page, Integer pageSize, String nextLinkURL)
            throws Exception {

        List<MyChannelResponse> channelIds = new ArrayList<>();

        // Fetch all channelIds associated user and store into list.
        while (true) {

            // invoke getChannels() method to get channels
            MyChannelResponses myChannelResponse = getChannels(btCookie, page, pageSize, nextLinkURL);
            List<PaginationLinks> links = myChannelResponse.getLinks();
            channelIds.addAll(myChannelResponse.getChannels());
            //Some logic
        }
    } // getMyChannelResponse() method close



    @Cacheable(value = "mychannel", key = "#root.args[0]")
    public MyChannelResponses getChannels(String btCookie, Integer page, Integer pageSize, String uri)
            throws Exception {
        try {
            log.debug("Entering Cookie: " + btCookie + " to get channels.");    
            // Calling Spring Boot Rest API to get channel associated btCookie

        } catch (Exception e) { 
            // throwing some exception
        }
    }// getChannels() method close
}       

Thank you.

2
  • In your dummy scenario which variable represents token ? Commented May 6, 2020 at 16:16
  • Hi @Hemant, In dummy scenario I was addressing to btCookie which is coming in request. Commented May 6, 2020 at 16:17

2 Answers 2

2

Change key in above code from both methods to this

@Cacheable(value = "mychannel", key = "#btCookie")
Sign up to request clarification or add additional context in comments.

10 Comments

I had tried with key = "#btCookie", but It is not working.
did you change it in method getMyChannelResponse as well ?
Yes, In both method changed.
Since morning, I am trying with all possible solution gone through Spring docs as well but none of the solution worked.
There is already answer for that - stackoverflow.com/q/8181768/7505731
|
0

Below code clear cache for every 2 minutes

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.google.common.cache.CacheBuilder;

@Configuration
public class CacheConfiguration extends CachingConfigurerSupport {

    private static final Logger log = LoggerFactory.getLogger(CacheConfiguration.class);

    @Bean
    @Override
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();

        log.info("cacheConfig");

        Cache getChannels = new ConcurrentMapCache("getChannels",
                CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.MINUTES).build().asMap(), false);

        cacheManager.setCaches(Arrays.asList(getChannels));

        return cacheManager;
    }

    @Override
    public KeyGenerator keyGenerator() {
        return new SimpleKeyGenerator();
    }

    @Override
    public CacheErrorHandler errorHandler() {
        return null;
    }

    @Override
    public CacheResolver cacheResolver() {
        return null;
    }

}

And Cacheable method will be

@Cacheable(value = "getChannels", key = "#btCookie", cacheManager="cacheManager")
    public List<MyChannelResponse> getMyChannelResponse(String btCookie, Integer page, Integer pageSize)
            throws Exception {

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.