Migration from 2.x to 3.x

300 views
Skip to first unread message

Samarth Gaur

unread,
Nov 20, 2023, 1:37:22 AM11/20/23
to ehcache-users
Hi All,

Following was the config and controller class being used by us for implementation of 2.x ehcache:

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;

/**
 * The type Cache config.
 */
@Configuration
public class CacheConfig {

    @Value("${cache.global.search.size}")
    private int globalSearchCacheSize;
    @Value("${cache.binge.size}")
    private int bingeCacheSize;
    @Value("${cache.help.center.size}")
    private int helpCenterCacheSize;
    @Value("${cache.binge.anywhere.size}")
    private int bingeAnywhereCacheSize;
    @Value("${cache.atv.size}")
    private int atvCacheSize;
    @Value("${cache.auto.complete.size}")
    private int autoCompleteCacheSize;
    @Value("${cache.global.search.eviction.policy}")
    private String globalSearchCacheEvictionPolicy;
    @Value("${cache.binge.eviction.policy}")
    private String bingeCacheEvictionPolicy;
    @Value("${cache.help.center.eviction.policy}")
    private String helpCenterCacheEvictionPolicy;
    @Value("${cache.binge.anywhere.eviction.policy}")
    private String bingeAnywhereCacheEvictionPolicy;
    @Value("${cache.atv.eviction.policy}")
    private String atvCacheEvictionPolicy;
    @Value("${cache.auto.complete.eviction.policy}")
    private String autoCompleteCacheEvictionPolicy;
    @Value("${cache.ttl.time.seconds}")
    private int ttlTime;

    @Value("${cache.ttl.time.seconds.freemium:600}")
    private int ttlTimeFreemium = 600;

    /**
     * Collect garbage of expired cache.
     */
    @Scheduled(fixedRate = 240000)
    public void collectGarbage() {
        System.gc();
    }

    /**
     * Test eh cache manager eh cache cache manager.
     *
     * @return the eh cache cache manager
     */
    @Bean
    public EhCacheCacheManager cacheManager() {
        CacheManager cacheManager = CacheManager.create();
        CacheConfiguration globalSearchConfig = new CacheConfiguration()
                .timeToLiveSeconds(ttlTime)
                .maxEntriesLocalHeap(globalSearchCacheSize)
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.fromString(globalSearchCacheEvictionPolicy))
                .name("globalSearch");
        CacheConfiguration atvConfig = new CacheConfiguration()
                .timeToLiveSeconds(ttlTime)
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.fromString(atvCacheEvictionPolicy))
                .maxEntriesLocalHeap(atvCacheSize)
                .name("atv");
        CacheConfiguration bingeConfig = new CacheConfiguration()
                .timeToLiveSeconds(ttlTime)
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.fromString(bingeCacheEvictionPolicy))
                .maxEntriesLocalHeap(bingeCacheSize)
                .name("binge");
        CacheConfiguration anywhereConfig = new CacheConfiguration()
                .timeToLiveSeconds(ttlTime)
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.fromString(bingeAnywhereCacheEvictionPolicy))
                .maxEntriesLocalHeap(bingeAnywhereCacheSize)
                .name("anywhere");
        CacheConfiguration autoCompleteConfig = new CacheConfiguration()
                .timeToLiveSeconds(ttlTime)
                .maxEntriesLocalHeap(autoCompleteCacheSize)
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.fromString(autoCompleteCacheEvictionPolicy))
                .name("autoComplete");
        CacheConfiguration helpCenterConfig = new CacheConfiguration()
                .timeToLiveSeconds(ttlTime)
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.fromString(helpCenterCacheEvictionPolicy))
                .maxEntriesLocalHeap(helpCenterCacheSize)
                .name("helpCenter");
        CacheConfiguration freemiumAutoCompleteConfig = new CacheConfiguration()
                .timeToLiveSeconds(ttlTimeFreemium)
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.fromString(autoCompleteCacheEvictionPolicy))
                .maxEntriesLocalHeap(globalSearchCacheSize)
                .name("freemiumAutoComplete");
        Cache globalSearchCache = new Cache(globalSearchConfig);
        Cache atvCache = new Cache(atvConfig);
        Cache bingeCache = new Cache(bingeConfig);
        Cache autoCompleteCache = new Cache(autoCompleteConfig);
        Cache anywhereCache = new Cache(anywhereConfig);
        Cache helpCenterCache = new Cache(helpCenterConfig);
        Cache freemiumAutocompleteCache = new Cache(freemiumAutoCompleteConfig);
        cacheManager.addCache(globalSearchCache);
        cacheManager.addCache(atvCache);
        cacheManager.addCache(bingeCache);
        cacheManager.addCache(autoCompleteCache);
        cacheManager.addCache(anywhereCache);
        cacheManager.addCache(helpCenterCache);
        cacheManager.addCache(freemiumAutocompleteCache);
        return new EhCacheCacheManager(cacheManager);
    }

}


In the above code, the eviction policy is LFU as defined in application.properties. I have replaced the above config with the below code where i am unable to understand how to implement the LFU Eviction policy:

package tv.videoready.searchconnector.config;

import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;

import java.time.Duration;

/**
* The type Cache config.
*/
@Configuration
public class CacheConfig {

@Value("${cache.global.search.size}")
private int globalSearchCacheSize;

@Value("${cache.binge.size}")
private int bingeCacheSize;

@Value("${cache.help.center.size}")
private int helpCenterCacheSize;

@Value("${cache.binge.anywhere.size}")
private int bingeAnywhereCacheSize;

@Value("${cache.atv.size}")
private int atvCacheSize;

@Value("${cache.auto.complete.size}")
private int autoCompleteCacheSize;

@Value("${cache.global.search.eviction.policy}")
private String globalSearchCacheEvictionPolicy;

@Value("${cache.binge.eviction.policy}")
private String bingeCacheEvictionPolicy;

@Value("${cache.help.center.eviction.policy}")
private String helpCenterCacheEvictionPolicy;

@Value("${cache.binge.anywhere.eviction.policy}")
private String bingeAnywhereCacheEvictionPolicy;

@Value("${cache.atv.eviction.policy}")
private String atvCacheEvictionPolicy;

@Value("${cache.auto.complete.eviction.policy}")
private String autoCompleteCacheEvictionPolicy;

@Value("${cache.ttl.time.seconds}")
private int ttlTime;

@Value("${cache.ttl.time.seconds.freemium:600}")
private int ttlTimeFreemium = 600;

/**
* Collect garbage of expired cache.
*/
@Scheduled(fixedRate = 240000)
public void collectGarbage() {
// No need for explicit garbage collection in Ehcache 3.x
}

/**
* Test eh cache manager eh cache cache manager.
*
* @return the eh cache cache manager
*/
@Bean
public CacheManager cacheManager() {
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build();
cacheManager.init();

// Configure caches
configureCache(cacheManager, "globalSearch", globalSearchCacheSize, ttlTime);
configureCache(cacheManager, "atv", atvCacheSize, ttlTime);
configureCache(cacheManager, "binge", bingeCacheSize, ttlTime);
configureCache(cacheManager, "anywhere", bingeAnywhereCacheSize, ttlTime);
configureCache(cacheManager, "autoComplete", autoCompleteCacheSize, ttlTime);
configureCache(cacheManager, "helpCenter", helpCenterCacheSize, ttlTime);
configureCache(cacheManager, "freemiumAutoComplete", globalSearchCacheSize, ttlTimeFreemium);

return cacheManager;
}

private void configureCache(CacheManager cacheManager, String cacheName, int maxEntries, int ttlInSeconds) {
CacheConfigurationBuilder<String, String> cacheConfig = CacheConfigurationBuilder
.newCacheConfigurationBuilder(String.class, String.class, ResourcePoolsBuilder.heap(maxEntries))
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(ttlInSeconds)));

cacheManager.createCache(cacheName, cacheConfig);
}
}


Apart from the above, i have a controller class as follows:

import net.sf.ehcache.management.CacheStatistics;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tv.videoready.searchconnector.config.CacheConfig;
import tv.videoready.searchconnector.util.GenericResponse;

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

/**
 * The type Cache controller.
 */
@RestController
@RequestMapping("admin/cache")
public class CacheController {
    private static final Logger log= LogManager.getLogger(CacheController.class);

    /**
     * The Cache config.
     */
    @Autowired
    CacheConfig cacheConfig;


    /**
     * Gets stats.
     *
     * @return the stats
     */
    @GetMapping("stats")
    public GenericResponse<Map<String, Map<String, String>>> getStats(@RequestHeader(value="true-client-ip",required = false) String trueClientIp,
                                                                      @RequestHeader(value="tpr-id",required = false) String tprId) {
        log.info("[AKAMAI_GRN] true-client-id :: {} and tpr-id :: {}",trueClientIp,tprId);
        EhCacheCacheManager cacheManager = cacheConfig.cacheManager();
        try {
            Map<String, Map<String, String>> data = new HashMap<>();
            for (String cache : cacheManager.getCacheNames()) {
                Map<String, String> stat = new LinkedHashMap<>();
                CacheStatistics stats = new CacheStatistics(
                        Objects.requireNonNull(cacheManager.getCacheManager()).getEhcache(cache));
                stat.put("cacheName", cache);
                stat.put("status", cacheManager.getCacheManager().getEhcache(cache).isDisabled()
                                   ? "disabled"
                                   : "enabled");
                stat.put("evictionPolicy",
                         stats.getEhcache().getCacheConfiguration().getMemoryStoreEvictionPolicy().toString());
                stat.put("timeToLiveInSeconds",
                         Long.toString(stats.getEhcache().getCacheConfiguration().getTimeToLiveSeconds()));
                stat.put("maxCacheSize",
                         Long.toString(stats.getEhcache().getCacheConfiguration().getMaxEntriesLocalHeap()));
                stat.put("currentObjectCountInCache",
                         Long.toString(stats.getEhcache().getKeysWithExpiryCheck().size()));
                stat.put("hits", Long.toString(stats.getCacheHits()));
                stat.put("misses", Long.toString(stats.getCacheMisses()));
                stat.put("hitPercentage", stats.getCacheHitPercentage() * 100 + " %");
                stat.put("missPercentage", stats.getCacheMissPercentage() * 100 + " %");
                data.put(cache, stat);
            }
            return new GenericResponse<>((data),
                                         HttpStatus.OK.value(),
                                         "Cache Stats fetched successfully.");
        } catch (Exception e) {
            e.printStackTrace();
            return new GenericResponse<>(
                    null,
                    HttpStatus.INTERNAL_SERVER_ERROR.value(),
                    "Exception Occurred while Calculating Stats: " + e.getMessage()
            );
        }
    }

    /**
     * Clear all caches generic response.
     *
     * @return the generic response
     */
    @GetMapping("clear")
    public GenericResponse<Map<String, Map<String, String>>> clearAllCaches(@RequestHeader(value="true-client-ip",required = false) String trueClientIp,
                                                                            @RequestHeader(value="tpr-id",required = false) String tprId) {
        log.info("[AKAMAI_GRN] true-client-id :: {} and tpr-id :: {}",trueClientIp,tprId);
        EhCacheCacheManager cacheManager = cacheConfig.cacheManager();
        try {
            Map<String, Map<String, String>> data = new HashMap<>();
            cacheManager.getCacheNames()
                        .forEach(cacheName -> {
                            data.put(cacheName, Collections.singletonMap("status", "fail"));
                            try {
                                Objects.requireNonNull(cacheManager.getCache(cacheName)).clear();
                            } catch (Exception ignored) {
                            }
                            data.put(cacheName, Collections.singletonMap("status", "success"));
                        });
            return new GenericResponse<>((data),
                                         HttpStatus.OK.value(),
                                         "Caches Cleared successfully.");
        } catch (Exception e) {
            e.printStackTrace();
            return new GenericResponse<>(
                    null,
                    HttpStatus.INTERNAL_SERVER_ERROR.value(),
                    "Exception Occurred while Clearing Caches: " + e.getMessage()
            );
        }
    }

    /**
     * Disable all caches generic response.
     *
     * @return the generic response
     */
    @GetMapping("disable")
    public GenericResponse<Map<String, Map<String, String>>> disableAllCaches(@RequestHeader(value="true-client-ip",required = false) String trueClientIp,
                                                                              @RequestHeader(value="tpr-id",required = false) String tprId) {
        log.info("[AKAMAI_GRN] true-client-id :: {} and tpr-id :: {}",trueClientIp,tprId);
        EhCacheCacheManager cacheManager = cacheConfig.cacheManager();
        try {
            Map<String, Map<String, String>> data = new HashMap<>();
            cacheManager.getCacheNames()
                        .forEach(cacheName -> {
                            data.put(cacheName, Collections.singletonMap("status", "enabled"));
                            try {
                                Objects.requireNonNull(cacheManager.getCacheManager()).getEhcache(cacheName)
                                       .setDisabled(true);
                            } catch (Exception ignored) {
                            }
                            data.put(cacheName, Collections.singletonMap("status", "disabled"));
                        });
            return new GenericResponse<>((data),
                                         HttpStatus.OK.value(),
                                         "Caches Cleared successfully.");
        } catch (Exception e) {
            e.printStackTrace();
            return new GenericResponse<>(
                    null,
                    HttpStatus.INTERNAL_SERVER_ERROR.value(),
                    "Exception Occurred while Clearing Caches: " + e.getMessage()
            );
        }
    }

    /**
     * Enable all caches generic response.
     *
     * @return the generic response
     */
    @GetMapping("enable")
    public GenericResponse<Map<String, Map<String, String>>> enableAllCaches(@RequestHeader(value="true-client-ip",required = false) String trueClientIp,
                                                                             @RequestHeader(value="tpr-id",required = false) String tprId) {
        log.info("[AKAMAI_GRN] true-client-id :: {} and tpr-id :: {}",trueClientIp,tprId);
        EhCacheCacheManager cacheManager = cacheConfig.cacheManager();
        try {
            Map<String, Map<String, String>> data = new HashMap<>();
            cacheManager.getCacheNames()
                        .forEach(cacheName -> {
                            data.put(cacheName, Collections.singletonMap("status", "disabled"));
                            try {
                                Objects.requireNonNull(cacheManager.getCacheManager()).getEhcache(cacheName)
                                       .setDisabled(false);
                            } catch (Exception ignored) {
                            }
                            data.put(cacheName, Collections.singletonMap("status", "enabled"));
                        });
            return new GenericResponse<>((data),
                                         HttpStatus.OK.value(),
                                         "Caches Cleared successfully.");
        } catch (Exception e) {
            e.printStackTrace();
            return new GenericResponse<>(
                    null,
                    HttpStatus.INTERNAL_SERVER_ERROR.value(),
                    "Exception Occurred while Clearing Caches: " + e.getMessage()
            );
        }
    }
}


In the above code, there are a lot of issues during migration as the getCacheNames(), EhCacheCacheManager, and various other elements are not available in 3.10.8. Can anyone help with the above please?

Regards,
Samarth Gaur
Reply all
Reply to author
Forward
0 new messages