1212import com .fasterxml .jackson .annotation .JsonInclude ;
1313import com .fasterxml .jackson .databind .json .JsonMapper ;
1414import com .fasterxml .jackson .datatype .jsr310 .JavaTimeModule ;
15- import com .giffing .bucket4j .spring .boot .starter .context .properties .Bucket4JBootProperties ;
1615import com .github .benmanes .caffeine .cache .Cache ;
1716import com .github .benmanes .caffeine .cache .Caffeine ;
1817import com .github .benmanes .caffeine .cache .Scheduler ;
18+ import com .github .benmanes .caffeine .jcache .CacheManagerImpl ;
19+ import com .github .benmanes .caffeine .jcache .configuration .CaffeineConfiguration ;
20+ import com .github .benmanes .caffeine .jcache .spi .CaffeineCachingProvider ;
1921import io .micrometer .common .util .StringUtils ;
2022import org .eclipse .openvsx .entities .ExtensionVersion ;
2123import org .eclipse .openvsx .json .ExtensionJson ;
2224import org .eclipse .openvsx .json .NamespaceDetailsJson ;
2325import org .eclipse .openvsx .search .SearchResult ;
2426import org .springframework .beans .factory .annotation .Value ;
27+ import org .springframework .boot .autoconfigure .condition .ConditionalOnExpression ;
2528import org .springframework .boot .autoconfigure .condition .ConditionalOnProperty ;
2629import org .springframework .boot .autoconfigure .data .redis .RedisProperties ;
2730import org .springframework .cache .CacheManager ;
2831import org .springframework .cache .annotation .EnableCaching ;
2932import org .springframework .cache .caffeine .CaffeineCacheManager ;
33+ import org .springframework .cache .jcache .JCacheCacheManager ;
3034import org .springframework .context .annotation .Bean ;
3135import org .springframework .context .annotation .Configuration ;
3236import org .springframework .context .annotation .Primary ;
3943import redis .clients .jedis .JedisCluster ;
4044import redis .clients .jedis .JedisPool ;
4145
46+ import java .net .URI ;
4247import java .time .Duration ;
48+ import java .util .OptionalLong ;
49+ import java .util .Properties ;
4350import java .util .stream .Collectors ;
4451
4552import static org .eclipse .openvsx .cache .CacheService .*;
@@ -103,13 +110,13 @@ public CacheManager fileCacheManager(
103110 }
104111
105112 @ Bean
106- @ ConditionalOnProperty ( prefix = Bucket4JBootProperties . PROPERTY_PREFIX , name = " cache-to-use" , havingValue = " redis-jedis" )
113+ @ ConditionalOnExpression ( "${bucket4j.enabled:false} && '${bucket4j. cache-to-use:}' == ' redis-jedis' " )
107114 public JedisPool jedisPool (RedisProperties properties ) {
108115 return new JedisPool (properties .getHost (), properties .getPort (), properties .getUsername (), properties .getPassword ());
109116 }
110117
111118 @ Bean
112- @ ConditionalOnProperty ( prefix = Bucket4JBootProperties . PROPERTY_PREFIX , name = " cache-to-use" , havingValue = " redis-cluster-jedis" )
119+ @ ConditionalOnExpression ( "${bucket4j.enabled:false} && '${bucket4j. cache-to-use:}' == ' redis-cluster-jedis' " )
113120 public JedisCluster jedisCluster (RedisProperties properties ) {
114121 var configBuilder = DefaultJedisClientConfig .builder ();
115122 var username = properties .getUsername ();
@@ -130,6 +137,69 @@ public JedisCluster jedisCluster(RedisProperties properties) {
130137
131138 @ Bean
132139 @ Primary
140+ @ ConditionalOnProperty (value = "ovsx.redis.enabled" , havingValue = "false" , matchIfMissing = true )
141+ public JCacheCacheManager caffeineCacheManager (
142+ @ Value ("${ovsx.caching.average-review-rating.ttl:P3D}" ) Duration averageReviewRatingTtl ,
143+ @ Value ("${ovsx.caching.average-review-rating.max-size:1}" ) long averageReviewRatingMaxSize ,
144+ @ Value ("${ovsx.caching.namespace-details-json.ttl:PT1H}" ) Duration namespaceDetailsJsonTtl ,
145+ @ Value ("${ovsx.caching.namespace-details-json.max-size:1024}" ) long namespaceDetailsJsonMaxSize ,
146+ @ Value ("${ovsx.caching.database-search.ttl:PT1H}" ) Duration databaseSearchTtl ,
147+ @ Value ("${ovsx.caching.database-search.max-size:1024}" ) long databaseSearchMaxSize ,
148+ @ Value ("${ovsx.caching.extension-json.ttl:PT1H}" ) Duration extensionJsonTtl ,
149+ @ Value ("${ovsx.caching.extension-json.max-size:1024}" ) long extensionJsonMaxSize ,
150+ @ Value ("${ovsx.caching.latest-extension-version.ttl:PT1H}" ) Duration latestExtensionVersionTtl ,
151+ @ Value ("${ovsx.caching.latest-extension-version.max-size:1024}" ) long latestExtensionVersionMaxSize ,
152+ @ Value ("${ovsx.caching.sitemap.ttl:PT1H}" ) Duration sitemapTtl ,
153+ @ Value ("${ovsx.caching.sitemap.max-size:1}" ) long sitemapMaxSize ,
154+ @ Value ("${ovsx.caching.malicious-extensions.ttl:P3D}" ) Duration maliciousExtensionsTtl ,
155+ @ Value ("${ovsx.caching.malicious-extensions.max-size:1}" ) long maliciousExtensionsMaxSize ,
156+ @ Value ("${ovsx.caching.rate-limiting.name:buckets}" ) String rateLimitingCacheName ,
157+ @ Value ("${ovsx.caching.rate-limiting.tti:PT1H}" ) Duration rateLimitingTti ,
158+ @ Value ("${ovsx.caching.rate-limiting.max-size:1024}" ) long rateLimitingMaxSize
159+ ) {
160+ var averageReviewRatingCache = createCaffeineConfiguration (averageReviewRatingTtl , averageReviewRatingMaxSize , false );
161+ var namespaceDetailsJsonCache = createCaffeineConfiguration (namespaceDetailsJsonTtl , namespaceDetailsJsonMaxSize , false );
162+ var databaseSearchCache = createCaffeineConfiguration (databaseSearchTtl , databaseSearchMaxSize , false );
163+ var extensionJsonCache = createCaffeineConfiguration (extensionJsonTtl , extensionJsonMaxSize , false );
164+ var latestExtensionVersionCache = createCaffeineConfiguration (latestExtensionVersionTtl , latestExtensionVersionMaxSize , false );
165+ var sitemapCache = createCaffeineConfiguration (sitemapTtl , sitemapMaxSize , false );
166+ var maliciousExtensionsCache = createCaffeineConfiguration (maliciousExtensionsTtl , maliciousExtensionsMaxSize , false );
167+ var rateLimitingCache = createCaffeineConfiguration (rateLimitingTti , rateLimitingMaxSize , true );
168+
169+ var cacheManager = new CacheManagerImpl (
170+ new CaffeineCachingProvider (),
171+ false ,
172+ URI .create ("com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider" ),
173+ Thread .currentThread ().getContextClassLoader (),
174+ new Properties ()
175+ );
176+
177+ cacheManager .createCache (CACHE_AVERAGE_REVIEW_RATING , averageReviewRatingCache );
178+ cacheManager .createCache (CACHE_NAMESPACE_DETAILS_JSON , namespaceDetailsJsonCache );
179+ cacheManager .createCache (CACHE_DATABASE_SEARCH , databaseSearchCache );
180+ cacheManager .createCache (CACHE_EXTENSION_JSON , extensionJsonCache );
181+ cacheManager .createCache (CACHE_LATEST_EXTENSION_VERSION , latestExtensionVersionCache );
182+ cacheManager .createCache (CACHE_SITEMAP , sitemapCache );
183+ cacheManager .createCache (CACHE_MALICIOUS_EXTENSIONS , maliciousExtensionsCache );
184+ cacheManager .createCache (rateLimitingCacheName , rateLimitingCache );
185+ return new JCacheCacheManager (cacheManager );
186+ }
187+
188+ private CaffeineConfiguration <Object , Object > createCaffeineConfiguration (Duration duration , long maxSize , boolean tti ) {
189+ var configuration = new CaffeineConfiguration <>();
190+ configuration .setMaximumSize (OptionalLong .of (maxSize ));
191+ if (tti ) {
192+ configuration .setExpireAfterAccess (OptionalLong .of (duration .toNanos ()));
193+ } else {
194+ configuration .setExpireAfterWrite (OptionalLong .of (duration .toNanos ()));
195+ }
196+
197+ return configuration ;
198+ }
199+
200+ @ Bean
201+ @ Primary
202+ @ ConditionalOnProperty (value = "ovsx.redis.enabled" , havingValue = "true" )
133203 public CacheManager redisCacheManager (
134204 RedisConnectionFactory redisConnectionFactory ,
135205 @ Value ("${ovsx.caching.average-review-rating.ttl:P3D}" ) Duration averageReviewRatingTtl ,
0 commit comments