package io.mangoo.providers; import java.net.URI; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; import org.ehcache.CacheManager; import org.ehcache.PersistentCacheManager; import org.ehcache.clustered.client.config.builders.ClusteringServiceConfigurationBuilder; import org.ehcache.config.CacheConfiguration; import org.ehcache.config.builders.CacheConfigurationBuilder; import org.ehcache.config.builders.CacheManagerBuilder; import org.ehcache.config.builders.ResourcePoolsBuilder; import org.ehcache.expiry.Duration; import org.ehcache.expiry.Expirations; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import io.mangoo.cache.Cache; import io.mangoo.cache.CacheImpl; import io.mangoo.configuration.Config; import io.mangoo.enums.CacheName; /** * * @author svenkubiak * */ @Singleton public class CacheProvider implements Provider<Cache> { private Map<String, Cache> caches = new HashMap<>(); private CacheManager cacheManager; private Cache cache; private static final int SIXTY = 60; private static final int THIRTY = 30; private static final int FORTY_THOUSAND_ELEMENTS = 40000; private static final int TWENTY_THOUSAND_ELEMENTS = 20000; @Inject public CacheProvider(Config config) { Objects.requireNonNull(config, "config can not be null"); if (config.isClusteredCached()) { CacheManagerBuilder<PersistentCacheManager> clusteredCacheManagerBuilder = CacheManagerBuilder.newCacheManagerBuilder() .with(ClusteringServiceConfigurationBuilder.cluster(URI.create(config.getCacheClusterUrl())) .autoCreate()); this.cacheManager = clusteredCacheManagerBuilder.build(true); } else { this.cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(); this.cacheManager.init(); } initApplicationCache(); initAuthenticationCache(); initRequestCache(); initServerEventCache(); initWebSocketCache(); } private void initApplicationCache() { CacheConfiguration<String, Object> configuration = CacheConfigurationBuilder .newCacheConfigurationBuilder(String.class, Object.class, ResourcePoolsBuilder.heap(TWENTY_THOUSAND_ELEMENTS)) .build(); this.cache = registerCacheConfiguration(CacheName.APPLICATION.toString(), configuration); } private void initAuthenticationCache() { CacheConfiguration<String, Object> configuration = CacheConfigurationBuilder .newCacheConfigurationBuilder(String.class, Object.class, ResourcePoolsBuilder.heap(TWENTY_THOUSAND_ELEMENTS)) .withExpiry(Expirations.timeToLiveExpiration(Duration.of(SIXTY, TimeUnit.MINUTES))) .build(); registerCacheConfiguration(CacheName.AUTH.toString(), configuration); } private void initRequestCache() { CacheConfiguration<String, Object> configuration = CacheConfigurationBuilder .newCacheConfigurationBuilder(String.class, Object.class, ResourcePoolsBuilder.heap(FORTY_THOUSAND_ELEMENTS)) .withExpiry(Expirations.timeToLiveExpiration(Duration.of(SIXTY, TimeUnit.SECONDS))) .build(); registerCacheConfiguration(CacheName.REQUEST.toString(), configuration); } private void initServerEventCache() { CacheConfiguration<String, Object> configuration = CacheConfigurationBuilder .newCacheConfigurationBuilder(String.class, Object.class, ResourcePoolsBuilder.heap(TWENTY_THOUSAND_ELEMENTS)) .withExpiry(Expirations.timeToIdleExpiration(Duration.of(THIRTY, TimeUnit.MINUTES))) .build(); registerCacheConfiguration(CacheName.SSE.toString(), configuration); } private void initWebSocketCache() { CacheConfiguration<String, Object> configuration = CacheConfigurationBuilder .newCacheConfigurationBuilder(String.class, Object.class, ResourcePoolsBuilder.heap(TWENTY_THOUSAND_ELEMENTS)) .withExpiry(Expirations.timeToIdleExpiration(Duration.of(THIRTY, TimeUnit.MINUTES))) .build(); registerCacheConfiguration(CacheName.WSS.toString(), configuration); } public Cache registerCacheConfiguration(String name, CacheConfiguration<String, Object> configuration) { cache = new CacheImpl(cacheManager.createCache(name, configuration)); this.caches.put(name, cache); return cache; } @Override public Cache get() { return this.cache; } /** * Retrieves a cache by its name from the cache pool * * @param name The name of the cache * @return An Cache instance */ public Cache getCache(CacheName name) { return getCache(name.toString()); } /** * Retrieves a cache by its name from the cache pool * * @param name The name of the cache * @return An Cache instance */ public Cache getCache(String name) { return this.caches.get(name); } /** * Closes all caches */ public void close() { cacheManager.close(); } }