From e9ec18534223efd0c02c7f1e5d61ea072d5375ca Mon Sep 17 00:00:00 2001 From: Ozan Gunalp Date: Thu, 17 Nov 2022 21:32:42 +0000 Subject: [PATCH] Configure redis client beans from config if a programmatic injection point exists. --- .../deployment/RedisClientProcessor.java | 21 +++++++ .../deployment/RedisDatasourceProcessor.java | 10 ++++ .../client/deployment/RedisNoConfTest.java | 3 +- .../runtime/client/RedisClientRecorder.java | 1 + .../runtime/client/config/RedisConfig.java | 17 +++++- .../kafka/RedisStateStore.java | 3 +- .../RedisWithInstanceInjectionResource.java | 57 +++++++++++++++++++ .../src/main/resources/application.properties | 1 + .../io/quarkus/redis/it/QuarkusRedisTest.java | 1 + 9 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisWithInstanceInjectionResource.java diff --git a/extensions/redis-client/deployment/src/main/java/io/quarkus/redis/client/deployment/RedisClientProcessor.java b/extensions/redis-client/deployment/src/main/java/io/quarkus/redis/client/deployment/RedisClientProcessor.java index f1912459a5450..2e0f540c20a6a 100644 --- a/extensions/redis-client/deployment/src/main/java/io/quarkus/redis/client/deployment/RedisClientProcessor.java +++ b/extensions/redis-client/deployment/src/main/java/io/quarkus/redis/client/deployment/RedisClientProcessor.java @@ -36,6 +36,7 @@ import io.quarkus.redis.client.RedisOptionsCustomizer; import io.quarkus.redis.client.reactive.ReactiveRedisClient; import io.quarkus.redis.runtime.client.RedisClientRecorder; +import io.quarkus.redis.runtime.client.config.RedisConfig; import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; import io.quarkus.vertx.deployment.VertxBuildItem; import io.vertx.redis.client.impl.types.BulkType; @@ -97,6 +98,8 @@ UnremovableBeanBuildItem makeHostsProviderAndOptionsCustomizerUnremovable() { @BuildStep @Record(ExecutionTime.RUNTIME_INIT) public void init(RedisClientRecorder recorder, + RedisBuildTimeConfig buildTimeConfig, + RedisConfig redisConfig, BeanArchiveIndexBuildItem indexBuildItem, BeanDiscoveryFinishedBuildItem beans, ShutdownContextBuildItem shutdown, @@ -117,6 +120,12 @@ public void init(RedisClientRecorder recorder, .findAny() .ifPresent(x -> names.add(DEFAULT_CLIENT_NAME)); + beans.getInjectionPoints().stream() + .filter(i -> SUPPORTED_INJECTION_TYPE.contains(i.getRequiredType().name())) + .filter(InjectionPointInfo::isProgrammaticLookup) + .findAny() + .ifPresent(x -> names.addAll(configuredClientNames(buildTimeConfig, redisConfig))); + // Inject the creation of the client when the application starts. recorder.initialize(vertxBuildItem.getVertx(), names); @@ -144,6 +153,18 @@ public void init(RedisClientRecorder recorder, recorder.cleanup(shutdown); } + static Set configuredClientNames(RedisBuildTimeConfig buildTimeConfig, RedisConfig redisConfig) { + Set names = new HashSet<>(); + // redis client names from dev services + if (buildTimeConfig.defaultDevService.devservices.enabled) { + names.add(DEFAULT_CLIENT_NAME); + } + names.addAll(buildTimeConfig.additionalDevServices.keySet()); + // redis client names declared in config + names.addAll(redisConfig.clientNames()); + return names; + } + static SyntheticBeanBuildItem configureAndCreateSyntheticBean(String name, Class type, Supplier supplier) { diff --git a/extensions/redis-client/deployment/src/main/java/io/quarkus/redis/client/deployment/RedisDatasourceProcessor.java b/extensions/redis-client/deployment/src/main/java/io/quarkus/redis/client/deployment/RedisDatasourceProcessor.java index 4021f154ca01b..6047373880493 100644 --- a/extensions/redis-client/deployment/src/main/java/io/quarkus/redis/client/deployment/RedisDatasourceProcessor.java +++ b/extensions/redis-client/deployment/src/main/java/io/quarkus/redis/client/deployment/RedisDatasourceProcessor.java @@ -2,6 +2,7 @@ import static io.quarkus.redis.client.deployment.RedisClientProcessor.REDIS_CLIENT_ANNOTATION; import static io.quarkus.redis.client.deployment.RedisClientProcessor.configureAndCreateSyntheticBean; +import static io.quarkus.redis.client.deployment.RedisClientProcessor.configuredClientNames; import static io.quarkus.redis.runtime.client.config.RedisConfig.DEFAULT_CLIENT_NAME; import java.util.Collection; @@ -25,6 +26,7 @@ import io.quarkus.redis.datasource.ReactiveRedisDataSource; import io.quarkus.redis.datasource.RedisDataSource; import io.quarkus.redis.runtime.client.RedisClientRecorder; +import io.quarkus.redis.runtime.client.config.RedisConfig; import io.quarkus.vertx.deployment.VertxBuildItem; public class RedisDatasourceProcessor { @@ -36,6 +38,8 @@ public class RedisDatasourceProcessor { @BuildStep @Record(ExecutionTime.RUNTIME_INIT) public void init(RedisClientRecorder recorder, + RedisBuildTimeConfig buildTimeConfig, + RedisConfig redisConfig, BeanArchiveIndexBuildItem indexBuildItem, BeanDiscoveryFinishedBuildItem beans, ShutdownContextBuildItem shutdown, @@ -56,6 +60,12 @@ public void init(RedisClientRecorder recorder, .findAny() .ifPresent(x -> names.add(DEFAULT_CLIENT_NAME)); + beans.getInjectionPoints().stream() + .filter(i -> SUPPORTED_INJECTION_TYPE.contains(i.getRequiredType().name())) + .filter(InjectionPointInfo::isProgrammaticLookup) + .findAny() + .ifPresent(x -> names.addAll(configuredClientNames(buildTimeConfig, redisConfig))); + // Inject the creation of the client when the application starts. recorder.initialize(vertxBuildItem.getVertx(), names); diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/RedisNoConfTest.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/RedisNoConfTest.java index 31e97ec8cd381..210513b5e1264 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/RedisNoConfTest.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/RedisNoConfTest.java @@ -18,7 +18,8 @@ public class RedisNoConfTest { @RegisterExtension static final QuarkusUnitTest unitTest = new QuarkusUnitTest() - .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)); + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)) + .overrideConfigKey("quarkus.redis.devservices.enabled", "false"); @Inject @Any diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/RedisClientRecorder.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/RedisClientRecorder.java index 9d841ee1fcaa0..716b070ab5028 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/RedisClientRecorder.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/RedisClientRecorder.java @@ -41,6 +41,7 @@ public RedisClientRecorder(RedisConfig rc) { public void initialize(RuntimeValue vertx, Set names) { this.vertx = Vertx.newInstance(vertx.getValue()); + names.addAll(config.clientNames()); _initialize(this.vertx, names); } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/config/RedisConfig.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/config/RedisConfig.java index 68cd8ddbce581..9cf189fe3022b 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/config/RedisConfig.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/config/RedisConfig.java @@ -1,13 +1,15 @@ package io.quarkus.redis.runtime.client.config; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import io.quarkus.runtime.annotations.ConfigDocMapKey; import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; -@ConfigRoot(phase = ConfigPhase.RUN_TIME, name = RedisConfig.REDIS_CONFIG_ROOT_NAME) +@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED, name = RedisConfig.REDIS_CONFIG_ROOT_NAME) public class RedisConfig { public final static String REDIS_CONFIG_ROOT_NAME = "redis"; public final static String HOSTS_CONFIG_NAME = "hosts"; @@ -53,4 +55,17 @@ public static boolean isDefaultClient(String name) { return DEFAULT_CLIENT_NAME.equalsIgnoreCase(name); } + public Set clientNames() { + Set names = new HashSet<>(); + if (this.namedRedisClients != null) { + names.addAll(this.namedRedisClients.keySet()); + } + if (this.defaultRedisClient != null) { + if (this.defaultRedisClient.hosts.isPresent()) { + names.add(DEFAULT_CLIENT_NAME); + } + } + return names; + } + } diff --git a/extensions/smallrye-reactive-messaging-kafka/runtime/src/main/java/io/quarkus/smallrye/reactivemessaging/kafka/RedisStateStore.java b/extensions/smallrye-reactive-messaging-kafka/runtime/src/main/java/io/quarkus/smallrye/reactivemessaging/kafka/RedisStateStore.java index 27c5c61427147..d73cbcbfc4a1b 100644 --- a/extensions/smallrye-reactive-messaging-kafka/runtime/src/main/java/io/quarkus/smallrye/reactivemessaging/kafka/RedisStateStore.java +++ b/extensions/smallrye-reactive-messaging-kafka/runtime/src/main/java/io/quarkus/smallrye/reactivemessaging/kafka/RedisStateStore.java @@ -9,6 +9,7 @@ import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Any; +import javax.enterprise.inject.Default; import javax.enterprise.inject.Instance; import javax.inject.Inject; @@ -65,7 +66,7 @@ public CheckpointStateStore create(KafkaConnectorIncomingConfiguration config, V .orElse(null); ReactiveRedisDataSource rds = clientName != null ? redisDataSource.select(RedisClientName.Literal.of(clientName)).get() - : redisDataSource.get(); + : redisDataSource.select(Default.Literal.INSTANCE).get(); ProcessingStateCodec stateCodec = CDIUtils.getInstanceById(stateCodecFactory, config.getChannel(), () -> { if (stateCodecFactory.isUnsatisfied()) { return VertxJsonProcessingStateCodec.FACTORY; diff --git a/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisWithInstanceInjectionResource.java b/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisWithInstanceInjectionResource.java new file mode 100644 index 0000000000000..cb06f78f7c1bf --- /dev/null +++ b/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisWithInstanceInjectionResource.java @@ -0,0 +1,57 @@ +package io.quarkus.redis.it; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import io.quarkus.redis.client.RedisClientName; +import io.quarkus.redis.datasource.ReactiveRedisDataSource; +import io.quarkus.redis.datasource.RedisDataSource; +import io.quarkus.redis.datasource.value.ReactiveValueCommands; +import io.quarkus.redis.datasource.value.ValueCommands; +import io.smallrye.mutiny.Uni; + +@Path("/quarkus-redis-with-instance") +@ApplicationScoped +public class RedisWithInstanceInjectionResource { + + private final ValueCommands blocking; + private final ReactiveValueCommands reactive; + + public RedisWithInstanceInjectionResource(@Any Instance ds, + @Any Instance reactiveDs) { + blocking = ds.select(RedisClientName.Literal.of("instance-client")).get().value(String.class); + reactive = reactiveDs.select(RedisClientName.Literal.of("instance-client")).get().value(String.class); + } + + // synchronous + @GET + @Path("/sync/{key}") + public String getSync(@PathParam("key") String key) { + return blocking.get(key); + } + + @POST + @Path("/sync/{key}") + public void setSync(@PathParam("key") String key, String value) { + blocking.set(key, value); + } + + // reactive + @GET + @Path("/reactive/{key}") + public Uni getReactive(@PathParam("key") String key) { + return reactive.get(key); + } + + @POST + @Path("/reactive/{key}") + public Uni setReactive(@PathParam("key") String key, String value) { + return this.reactive.set(key, value); + } + +} diff --git a/integration-tests/redis-client/src/main/resources/application.properties b/integration-tests/redis-client/src/main/resources/application.properties index e6c2f95d26e21..01f0e74a02688 100644 --- a/integration-tests/redis-client/src/main/resources/application.properties +++ b/integration-tests/redis-client/src/main/resources/application.properties @@ -4,5 +4,6 @@ quarkus.redis.named-reactive-client.hosts=redis://localhost:6379/1 quarkus.redis.named-client-legacy.hosts=redis://localhost:6379/4 quarkus.redis.named-reactive-client-legacy.hosts=redis://localhost:6379/4 quarkus.redis.parameter-injection.hosts=redis://localhost:6379/2 +quarkus.redis.instance-client.hosts=redis://localhost:6379/5 # use DB 3 quarkus.redis.provided-hosts.hosts-provider-name=test-hosts-provider diff --git a/integration-tests/redis-client/src/test/java/io/quarkus/redis/it/QuarkusRedisTest.java b/integration-tests/redis-client/src/test/java/io/quarkus/redis/it/QuarkusRedisTest.java index a8f8d09386745..238584da636e7 100644 --- a/integration-tests/redis-client/src/test/java/io/quarkus/redis/it/QuarkusRedisTest.java +++ b/integration-tests/redis-client/src/test/java/io/quarkus/redis/it/QuarkusRedisTest.java @@ -18,6 +18,7 @@ class QuarkusRedisTest { "/quarkus-redis", "/quarkus-redis-with-name", "/quarkus-redis-with-name-legacy", + "/quarkus-redis-with-instance", "/quarkus-redis-provided-hosts", "/quarkus-redis-parameter-injection-legacy" };