Skip to content

Commit c016122

Browse files
committed
Jedis & Lettuce modules added
Cache Redis module refactored and new replacement for old Redis cache module introduced Old Redis Cache module deprecated but not removed for compatibility
1 parent 8eb1479 commit c016122

File tree

170 files changed

+2650
-4959
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

170 files changed

+2650
-4959
lines changed

cache/cache-annotation-processor/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ dependencies {
88
testImplementation testFixtures(project(":annotation-processor-common"))
99
testImplementation project(":internal:test-logging")
1010
testImplementation project(":cache:cache-caffeine")
11-
testImplementation project(":cache:cache-redis")
11+
testImplementation project(":cache:cache-redis-lettuce")
1212
testImplementation project(":json:json-common")
1313
testImplementation project(":config:config-common")
1414
}

cache/cache-annotation-processor/src/main/java/ru/tinkoff/kora/cache/annotation/processor/CacheAnnotationProcessor.java

Lines changed: 134 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,23 @@ public class CacheAnnotationProcessor extends AbstractKoraProcessor {
2929

3030
private static final ClassName ANNOTATION_CACHE = ClassName.get("ru.tinkoff.kora.cache.annotation", "Cache");
3131

32-
private static final ClassName CAFFEINE_TELEMETRY = ClassName.get("ru.tinkoff.kora.cache.caffeine", "CaffeineCacheTelemetry");
32+
private static final ClassName CACHE_TELEMETRY_FACTORY = ClassName.get("ru.tinkoff.kora.cache.telemetry", "CacheTelemetryFactory");
33+
3334
private static final ClassName CAFFEINE_CACHE = ClassName.get("ru.tinkoff.kora.cache.caffeine", "CaffeineCache");
3435
private static final ClassName CAFFEINE_CACHE_FACTORY = ClassName.get("ru.tinkoff.kora.cache.caffeine", "CaffeineCacheFactory");
3536
private static final ClassName CAFFEINE_CACHE_CONFIG = ClassName.get("ru.tinkoff.kora.cache.caffeine", "CaffeineCacheConfig");
3637
private static final ClassName CAFFEINE_CACHE_IMPL = ClassName.get("ru.tinkoff.kora.cache.caffeine", "AbstractCaffeineCache");
3738

39+
@Deprecated
3840
private static final ClassName REDIS_TELEMETRY = ClassName.get("ru.tinkoff.kora.cache.redis", "RedisCacheTelemetry");
41+
@Deprecated
42+
private static final ClassName REDIS_CACHE_OLD_CLIENT = ClassName.get("ru.tinkoff.kora.cache.redis", "RedisCacheClient");
43+
3944
private static final ClassName REDIS_CACHE = ClassName.get("ru.tinkoff.kora.cache.redis", "RedisCache");
4045
private static final ClassName REDIS_CACHE_IMPL = ClassName.get("ru.tinkoff.kora.cache.redis", "AbstractRedisCache");
4146
private static final ClassName REDIS_CACHE_CONFIG = ClassName.get("ru.tinkoff.kora.cache.redis", "RedisCacheConfig");
42-
private static final ClassName REDIS_CACHE_CLIENT = ClassName.get("ru.tinkoff.kora.cache.redis", "RedisCacheClient");
47+
private static final ClassName REDIS_CACHE_SYNC_CLIENT = ClassName.get("ru.tinkoff.kora.cache.redis", "RedisCacheClient");
48+
private static final ClassName REDIS_CACHE_ASYNC_CLIENT = ClassName.get("ru.tinkoff.kora.cache.redis", "RedisCacheAsyncClient");
4349
private static final ClassName REDIS_CACHE_MAPPER_KEY = ClassName.get("ru.tinkoff.kora.cache.redis", "RedisCacheKeyMapper");
4450
private static final ClassName REDIS_CACHE_MAPPER_VALUE = ClassName.get("ru.tinkoff.kora.cache.redis", "RedisCacheValueMapper");
4551

@@ -217,8 +223,8 @@ private MethodSpec getCacheRedisKeyMapperForRecord(DeclaredType keyType) {
217223

218224
var keyName = "_key" + (i + 1);
219225
keyBuilder.addStatement("var $L = $L.apply($T.requireNonNull(key.$L(), $S))",
220-
keyName, mapperName, Objects.class, recordField.getSimpleName().toString(),
221-
"Cache key '%s' field '%s' must be non null".formatted(keyType.asElement().toString(), recordField.getSimpleName().toString()));
226+
keyName, mapperName, Objects.class, recordField.getSimpleName().toString(),
227+
"Cache key '%s' field '%s' must be non null".formatted(keyType.asElement().toString(), recordField.getSimpleName().toString()));
222228

223229
if (i == 0) {
224230
compositeKeyBuilder.add("var _compositeKey = new byte[");
@@ -276,76 +282,150 @@ private MethodSpec getCacheMethodImpl(TypeElement cacheContract, ParameterizedTy
276282
.build())
277283
.build())
278284
.addParameter(CAFFEINE_CACHE_FACTORY, "factory")
279-
.addParameter(CAFFEINE_TELEMETRY, "telemetry")
280-
.addStatement("return new $T(config, factory, telemetry)", cacheImplName)
285+
.addParameter(CACHE_TELEMETRY_FACTORY, "telemetryFactory")
286+
.addStatement("return new $T(config, factory, telemetryFactory)", cacheImplName)
281287
.returns(TypeName.get(cacheContract.asType()))
282288
.build();
283289
}
290+
284291
if (cacheType.rawType.equals(REDIS_CACHE)) {
285-
var keyType = cacheType.typeArguments.get(0);
286-
var valueType = cacheType.typeArguments.get(1);
287-
var keyMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_KEY, keyType);
288-
var valueMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_VALUE, valueType);
289-
290-
final DeclaredType cacheDeclaredType = cacheContract.getInterfaces().stream()
291-
.filter(i -> ClassName.get(i).equals(cacheType))
292-
.map(i -> (DeclaredType) i)
293-
.findFirst()
294-
.orElseThrow();
295-
296-
var valueParamBuilder = ParameterSpec.builder(valueMapperType, "valueMapper");
297-
final Set<String> valueTags = TagUtils.parseTagValue(cacheDeclaredType.getTypeArguments().get(1));
298-
if (!valueTags.isEmpty()) {
299-
valueParamBuilder.addAnnotation(TagUtils.makeAnnotationSpec(valueTags));
292+
if (cacheType.annotations.stream().anyMatch(a -> a.type.equals(TypeName.get(Deprecated.class)))) {
293+
return getCacheRedisDeprecatedMethod(cacheContract, cacheType, cacheImplName, methodName);
294+
} else {
295+
return getCacheRedisMethod(cacheContract, cacheType, cacheImplName, methodName);
300296
}
297+
}
301298

302-
var keyParamBuilder = ParameterSpec.builder(keyMapperType, "keyMapper");
303-
final Set<String> keyTags = TagUtils.parseTagValue(cacheDeclaredType.getTypeArguments().get(0));
304-
if (!keyTags.isEmpty()) {
305-
keyParamBuilder.addAnnotation(TagUtils.makeAnnotationSpec(keyTags));
306-
}
299+
throw new IllegalArgumentException("Unknown cache implementation type: " + cacheType.rawType);
300+
}
307301

308-
return MethodSpec.methodBuilder(methodName)
309-
.addModifiers(Modifier.DEFAULT, Modifier.PUBLIC)
310-
.addParameter(ParameterSpec.builder(REDIS_CACHE_CONFIG, "config")
311-
.addAnnotation(AnnotationSpec.builder(CommonClassNames.tag)
312-
.addMember("value", "$T.class", cacheContract)
313-
.build())
302+
private MethodSpec getCacheRedisMethod(TypeElement cacheContract,
303+
ParameterizedTypeName cacheType,
304+
ClassName cacheImplName,
305+
String methodName) {
306+
var keyType = cacheType.typeArguments.get(0);
307+
var valueType = cacheType.typeArguments.get(1);
308+
var keyMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_KEY, keyType);
309+
var valueMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_VALUE, valueType);
310+
311+
final DeclaredType cacheDeclaredType = cacheContract.getInterfaces().stream()
312+
.filter(i -> ClassName.get(i).equals(cacheType))
313+
.map(i -> (DeclaredType) i)
314+
.findFirst()
315+
.orElseThrow();
316+
317+
var valueParamBuilder = ParameterSpec.builder(valueMapperType, "valueMapper");
318+
final Set<String> valueTags = TagUtils.parseTagValue(cacheDeclaredType.getTypeArguments().get(1));
319+
if (!valueTags.isEmpty()) {
320+
valueParamBuilder.addAnnotation(TagUtils.makeAnnotationSpec(valueTags));
321+
}
322+
323+
var keyParamBuilder = ParameterSpec.builder(keyMapperType, "keyMapper");
324+
final Set<String> keyTags = TagUtils.parseTagValue(cacheDeclaredType.getTypeArguments().get(0));
325+
if (!keyTags.isEmpty()) {
326+
keyParamBuilder.addAnnotation(TagUtils.makeAnnotationSpec(keyTags));
327+
}
328+
329+
return MethodSpec.methodBuilder(methodName)
330+
.addModifiers(Modifier.DEFAULT, Modifier.PUBLIC)
331+
.addParameter(ParameterSpec.builder(REDIS_CACHE_CONFIG, "config")
332+
.addAnnotation(AnnotationSpec.builder(CommonClassNames.tag)
333+
.addMember("value", "$T.class", cacheContract)
314334
.build())
315-
.addParameter(REDIS_CACHE_CLIENT, "redisClient")
316-
.addParameter(REDIS_TELEMETRY, "telemetry")
317-
.addParameter(keyParamBuilder.build())
318-
.addParameter(valueParamBuilder.build())
319-
.addStatement("return new $T(config, redisClient, telemetry, keyMapper, valueMapper)", cacheImplName)
320-
.returns(TypeName.get(cacheContract.asType()))
321-
.build();
335+
.build())
336+
.addParameter(REDIS_CACHE_SYNC_CLIENT, "redisSyncClient")
337+
.addParameter(REDIS_CACHE_ASYNC_CLIENT, "redisAsyncClient")
338+
.addParameter(CACHE_TELEMETRY_FACTORY, "telemetryFactory")
339+
.addParameter(keyParamBuilder.build())
340+
.addParameter(valueParamBuilder.build())
341+
.addStatement("return new $T(config, redisSyncClient, redisAsyncClient, telemetryFactory, keyMapper, valueMapper)", cacheImplName)
342+
.returns(TypeName.get(cacheContract.asType()))
343+
.build();
344+
}
345+
346+
@Deprecated
347+
private MethodSpec getCacheRedisDeprecatedMethod(TypeElement cacheContract,
348+
ParameterizedTypeName cacheType,
349+
ClassName cacheImplName,
350+
String methodName) {
351+
var keyType = cacheType.typeArguments.get(0);
352+
var valueType = cacheType.typeArguments.get(1);
353+
var keyMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_KEY, keyType);
354+
var valueMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_VALUE, valueType);
355+
356+
final DeclaredType cacheDeclaredType = cacheContract.getInterfaces().stream()
357+
.filter(i -> ClassName.get(i).equals(cacheType))
358+
.map(i -> (DeclaredType) i)
359+
.findFirst()
360+
.orElseThrow();
361+
362+
var valueParamBuilder = ParameterSpec.builder(valueMapperType, "valueMapper");
363+
final Set<String> valueTags = TagUtils.parseTagValue(cacheDeclaredType.getTypeArguments().get(1));
364+
if (!valueTags.isEmpty()) {
365+
valueParamBuilder.addAnnotation(TagUtils.makeAnnotationSpec(valueTags));
366+
}
367+
368+
var keyParamBuilder = ParameterSpec.builder(keyMapperType, "keyMapper");
369+
final Set<String> keyTags = TagUtils.parseTagValue(cacheDeclaredType.getTypeArguments().get(0));
370+
if (!keyTags.isEmpty()) {
371+
keyParamBuilder.addAnnotation(TagUtils.makeAnnotationSpec(keyTags));
322372
}
323-
throw new IllegalArgumentException("Unknown cache type: " + cacheType.rawType);
373+
374+
return MethodSpec.methodBuilder(methodName)
375+
.addModifiers(Modifier.DEFAULT, Modifier.PUBLIC)
376+
.addParameter(ParameterSpec.builder(REDIS_CACHE_CONFIG, "config")
377+
.addAnnotation(AnnotationSpec.builder(CommonClassNames.tag)
378+
.addMember("value", "$T.class", cacheContract)
379+
.build())
380+
.build())
381+
.addParameter(REDIS_CACHE_OLD_CLIENT, "redisClient")
382+
.addParameter(REDIS_TELEMETRY, "telemetry")
383+
.addParameter(keyParamBuilder.build())
384+
.addParameter(valueParamBuilder.build())
385+
.addStatement("return new $T(config, redisClient, telemetry, keyMapper, valueMapper)", cacheImplName)
386+
.returns(TypeName.get(cacheContract.asType()))
387+
.build();
324388
}
325389

326390
private MethodSpec getCacheConstructor(String configPath, ParameterizedTypeName cacheContract) {
327391
if (cacheContract.rawType.equals(CAFFEINE_CACHE)) {
328392
return MethodSpec.constructorBuilder()
329393
.addParameter(CAFFEINE_CACHE_CONFIG, "config")
330394
.addParameter(CAFFEINE_CACHE_FACTORY, "factory")
331-
.addParameter(CAFFEINE_TELEMETRY, "telemetry")
332-
.addStatement("super($S, config, factory, telemetry)", configPath)
395+
.addParameter(CACHE_TELEMETRY_FACTORY, "telemetryFactory")
396+
.addStatement("super($S, config, factory, telemetryFactory)", configPath)
333397
.build();
334398
}
335399

336400
if (cacheContract.rawType.equals(REDIS_CACHE)) {
337-
var keyType = cacheContract.typeArguments.get(0);
338-
var valueType = cacheContract.typeArguments.get(1);
339-
var keyMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_KEY, keyType);
340-
var valueMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_VALUE, valueType);
341-
return MethodSpec.constructorBuilder()
342-
.addParameter(REDIS_CACHE_CONFIG, "config")
343-
.addParameter(REDIS_CACHE_CLIENT, "redisClient")
344-
.addParameter(REDIS_TELEMETRY, "telemetry")
345-
.addParameter(keyMapperType, "keyMapper")
346-
.addParameter(valueMapperType, "valueMapper")
347-
.addStatement("super($S, config, redisClient, telemetry, keyMapper, valueMapper)", configPath)
348-
.build();
401+
if (cacheContract.annotations.stream().anyMatch(a -> a.type.equals(TypeName.get(Deprecated.class)))) {
402+
var keyType = cacheContract.typeArguments.get(0);
403+
var valueType = cacheContract.typeArguments.get(1);
404+
var keyMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_KEY, keyType);
405+
var valueMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_VALUE, valueType);
406+
return MethodSpec.constructorBuilder()
407+
.addParameter(REDIS_CACHE_CONFIG, "config")
408+
.addParameter(REDIS_CACHE_OLD_CLIENT, "redisClient")
409+
.addParameter(REDIS_TELEMETRY, "telemetry")
410+
.addParameter(keyMapperType, "keyMapper")
411+
.addParameter(valueMapperType, "valueMapper")
412+
.addStatement("super($S, config, redisClient, telemetry, keyMapper, valueMapper)", configPath)
413+
.build();
414+
} else {
415+
var keyType = cacheContract.typeArguments.get(0);
416+
var valueType = cacheContract.typeArguments.get(1);
417+
var keyMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_KEY, keyType);
418+
var valueMapperType = ParameterizedTypeName.get(REDIS_CACHE_MAPPER_VALUE, valueType);
419+
return MethodSpec.constructorBuilder()
420+
.addParameter(REDIS_CACHE_CONFIG, "config")
421+
.addParameter(REDIS_CACHE_SYNC_CLIENT, "redisSyncClient")
422+
.addParameter(REDIS_CACHE_ASYNC_CLIENT, "redisAsyncClient")
423+
.addParameter(CACHE_TELEMETRY_FACTORY, "telemetryFactory")
424+
.addParameter(keyMapperType, "keyMapper")
425+
.addParameter(valueMapperType, "valueMapper")
426+
.addStatement("super($S, config, redisSyncClient, redisAsyncClient, telemetryFactory, keyMapper, valueMapper)", configPath)
427+
.build();
428+
}
349429
}
350430

351431
throw new IllegalArgumentException("Unknown cache type: " + cacheContract.rawType);

cache/cache-annotation-processor/src/test/java/ru/tinkoff/kora/cache/annotation/processor/AsyncCacheAopTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private CacheableAsync getService() {
4141
final Constructor<?> cacheConstructor = cacheClass.getDeclaredConstructors()[0];
4242
cacheConstructor.setAccessible(true);
4343
cache = (DummyCache21) cacheConstructor.newInstance(CacheRunner.getCaffeineConfig(),
44-
caffeineCacheFactory(null), caffeineCacheTelemetry(null, null));
44+
caffeineCacheFactory(null), defaultCacheTelemetryFactory(null, null, null));
4545

4646
var serviceClass = classLoader.loadClass(CACHED_SERVICE);
4747
if (serviceClass == null) {

cache/cache-annotation-processor/src/test/java/ru/tinkoff/kora/cache/annotation/processor/AsyncCacheManyAopTests.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import ru.tinkoff.kora.cache.annotation.processor.testdata.async.CacheableAsyncMany;
1111
import ru.tinkoff.kora.cache.caffeine.CaffeineCacheModule;
1212
import ru.tinkoff.kora.cache.redis.RedisCacheKeyMapper;
13-
import ru.tinkoff.kora.cache.redis.RedisCacheMapperModule;
1413
import ru.tinkoff.kora.cache.redis.RedisCacheModule;
1514

1615
import java.lang.reflect.Constructor;
@@ -51,7 +50,7 @@ private CacheableAsyncMany getService() {
5150
final Constructor<?> cacheConstructor1 = cacheClass1.getDeclaredConstructors()[0];
5251
cacheConstructor1.setAccessible(true);
5352
cache1 = (DummyCache21) cacheConstructor1.newInstance(CacheRunner.getCaffeineConfig(),
54-
caffeineCacheFactory(null), caffeineCacheTelemetry(null, null));
53+
caffeineCacheFactory(null), defaultCacheTelemetryFactory(null, null, null));
5554

5655
var cacheClass2 = classLoader.loadClass(CACHED_IMPL_2);
5756
if (cacheClass2 == null) {
@@ -62,7 +61,7 @@ private CacheableAsyncMany getService() {
6261
cacheConstructor2.setAccessible(true);
6362
final Map<ByteBuffer, ByteBuffer> cache = new HashMap<>();
6463
cache2 = (DummyCache22) cacheConstructor2.newInstance(CacheRunner.getRedisConfig(),
65-
CacheRunner.lettuceClient(cache), redisCacheTelemetry(null, null),
64+
CacheRunner.lettuceSyncClient(cache), CacheRunner.lettuceAsyncClient(cache), defaultCacheTelemetryFactory(null, null, null),
6665
(RedisCacheKeyMapper<DummyCache22.Key>) key -> {
6766
var _key1 = key.k1().getBytes(StandardCharsets.UTF_8);
6867
var _key2 = key.k2().toString().getBytes(StandardCharsets.UTF_8);

cache/cache-annotation-processor/src/test/java/ru/tinkoff/kora/cache/annotation/processor/AsyncCacheManyOptionalAopTests.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import ru.tinkoff.kora.aop.annotation.processor.AopAnnotationProcessor;
88
import ru.tinkoff.kora.cache.annotation.processor.testcache.DummyCache21;
99
import ru.tinkoff.kora.cache.annotation.processor.testcache.DummyCache22;
10-
import ru.tinkoff.kora.cache.annotation.processor.testdata.async.CacheableAsyncMany;
1110
import ru.tinkoff.kora.cache.annotation.processor.testdata.async.CacheableAsyncManyOptional;
1211
import ru.tinkoff.kora.cache.caffeine.CaffeineCacheModule;
1312
import ru.tinkoff.kora.cache.redis.RedisCacheKeyMapper;
@@ -51,7 +50,7 @@ private CacheableAsyncManyOptional getService() {
5150
final Constructor<?> cacheConstructor1 = cacheClass1.getDeclaredConstructors()[0];
5251
cacheConstructor1.setAccessible(true);
5352
cache1 = (DummyCache21) cacheConstructor1.newInstance(CacheRunner.getCaffeineConfig(),
54-
caffeineCacheFactory(null), caffeineCacheTelemetry(null, null));
53+
caffeineCacheFactory(null), defaultCacheTelemetryFactory(null, null, null));
5554

5655
var cacheClass2 = classLoader.loadClass(CACHED_IMPL_2);
5756
if (cacheClass2 == null) {
@@ -62,7 +61,7 @@ private CacheableAsyncManyOptional getService() {
6261
cacheConstructor2.setAccessible(true);
6362
final Map<ByteBuffer, ByteBuffer> cache = new HashMap<>();
6463
cache2 = (DummyCache22) cacheConstructor2.newInstance(CacheRunner.getRedisConfig(),
65-
CacheRunner.lettuceClient(cache), redisCacheTelemetry(null, null),
64+
CacheRunner.lettuceSyncClient(cache), CacheRunner.lettuceAsyncClient(cache), defaultCacheTelemetryFactory(null, null, null),
6665
(RedisCacheKeyMapper<DummyCache22.Key>) key -> {
6766
var _key1 = key.k1().getBytes(StandardCharsets.UTF_8);
6867
var _key2 = key.k2().toString().getBytes(StandardCharsets.UTF_8);

cache/cache-annotation-processor/src/test/java/ru/tinkoff/kora/cache/annotation/processor/AsyncCacheOneAopTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private CacheableAsyncOne getService() {
4141
final Constructor<?> cacheConstructor = cacheClass.getDeclaredConstructors()[0];
4242
cacheConstructor.setAccessible(true);
4343
cache = (DummyCache11) cacheConstructor.newInstance(CacheRunner.getCaffeineConfig(),
44-
caffeineCacheFactory(null), caffeineCacheTelemetry(null, null));
44+
caffeineCacheFactory(null), defaultCacheTelemetryFactory(null, null, null));
4545

4646
var serviceClass = classLoader.loadClass(CACHED_SERVICE);
4747
if (serviceClass == null) {

0 commit comments

Comments
 (0)