From d7842f983f719c19785080da7179ce9c02c9e80a Mon Sep 17 00:00:00 2001 From: Katia Aresti Date: Sun, 23 Apr 2023 15:48:03 +0200 Subject: [PATCH] Adds infinispan caches configuration resource build property --- .../asciidoc/infinispan-client-reference.adoc | 22 +++- .../infinispan-client/deployment/pom.xml | 12 ++ .../deployment/InfinispanClientProcessor.java | 20 ++++ .../InfinispanConfigurationSetupTest.java | 61 ++++++++++ ...nispanDefaultMinimalConfigurationTest.java | 38 ++++++ ...NamedInfinispanConfigurationSetupTest.java | 48 ++++++++ .../cache-config-application.properties | 33 ++++++ .../resources/distributed-cache-config.xml | 1 + .../src/test/resources/local-cache-config.xml | 1 + .../resources/minimal-application.properties | 7 ++ ...ltiple-cache-config-application.properties | 20 ++++ .../InfinispanClientBuildTimeConfig.java | 29 ++++- .../runtime/InfinispanClientProducer.java | 109 ++++++++++++------ .../InfinispanClientRuntimeConfig.java | 23 +--- .../InfinispanClientsBuildTimeConfig.java | 4 +- .../src/main/resources/application.properties | 10 +- 16 files changed, 370 insertions(+), 68 deletions(-) create mode 100644 extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/InfinispanConfigurationSetupTest.java create mode 100644 extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/InfinispanDefaultMinimalConfigurationTest.java create mode 100644 extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/MultipleNamedInfinispanConfigurationSetupTest.java create mode 100644 extensions/infinispan-client/deployment/src/test/resources/cache-config-application.properties create mode 100644 extensions/infinispan-client/deployment/src/test/resources/distributed-cache-config.xml create mode 100644 extensions/infinispan-client/deployment/src/test/resources/local-cache-config.xml create mode 100644 extensions/infinispan-client/deployment/src/test/resources/minimal-application.properties create mode 100644 extensions/infinispan-client/deployment/src/test/resources/multiple-cache-config-application.properties diff --git a/docs/src/main/asciidoc/infinispan-client-reference.adoc b/docs/src/main/asciidoc/infinispan-client-reference.adoc index 8ee6a65733c0b..49bdb980801b5 100644 --- a/docs/src/main/asciidoc/infinispan-client-reference.adoc +++ b/docs/src/main/asciidoc/infinispan-client-reference.adoc @@ -169,14 +169,24 @@ to create it on first access, use one of the following properties: [source,properties] ---- -quarkus.infinispan-client.cache.books.configuration-uri=cacheConfig.json <1> -quarkus.infinispan-client.cache.magazine.configuration= <2> +quarkus.infinispan-client.cache.magazine.configuration= <1> +quarkus.infinispan-client.cache.books.configuration-resource=booksDistributedCache.json <2> +quarkus.infinispan-client.cache.authors.configuration-uri=/file/authorsIndexedCache.yaml <3> ---- -<1> The file name located under the `resources` folder that contains the configuration of the 'books' cache -<2> The configuration in xml of the 'magazine' (yaml and json are also supported) +<1> The configuration in xml of the 'magazine' (yaml and json are also supported) +<2> The file name located under the `resources` folder that contains the configuration of the 'books' cache +<3> A provided file URI. The file URI can also be a file under resources -If both `configuration-uri` and `configuration` are configured for the same cache with the same Quarkus profile, -`configuration-uri` gets preference over `configuration`. +If `configuration-resource`, `configuration` and `configuration-uri` are configured for the same cache with +the same Quarkus profile, `configuration-uri` gets the highest preference, over `configuration-resource` and `configuration`. +`configuration-resource` gets preference over `configuration`. + +[WARNING] +==== +The `configuration-resource` is build time property and the file will be included in the native build automatically. +`configuration-uri` can also point to a file under the `resources` folder. However, the file won't be automatically included +in the native executable, unless you configure the property `quarkus.native.resources.includes`. +==== [TIP] ==== diff --git a/extensions/infinispan-client/deployment/pom.xml b/extensions/infinispan-client/deployment/pom.xml index bef2b1168ff34..e0b7dadb2d40f 100644 --- a/extensions/infinispan-client/deployment/pom.xml +++ b/extensions/infinispan-client/deployment/pom.xml @@ -61,6 +61,18 @@ quarkus-kubernetes-service-binding-spi + + io.quarkus + quarkus-junit5-internal + test + + + + org.assertj + assertj-core + test + + org.infinispan infinispan-server-testdriver-core diff --git a/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java b/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java index 1d871298e268d..58201a89f0b4f 100644 --- a/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java +++ b/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java @@ -85,6 +85,7 @@ import io.quarkus.deployment.builditem.NativeImageFeatureBuildItem; import io.quarkus.deployment.builditem.SystemPropertyBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageConfigBuildItem; +import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageSecurityProviderBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; @@ -192,6 +193,7 @@ InfinispanPropertiesBuildItem setup(ApplicationArchivesBuildItem applicationArch BuildProducer nativeImageConfig, BuildProducer infinispanClientNames, MarshallingBuildItem marshallingBuildItem, + BuildProducer resourceBuildItem, CombinedIndexBuildItem applicationIndexBuildItem) throws ClassNotFoundException, IOException { feature.produce(new FeatureBuildItem(Feature.INFINISPAN_CLIENT)); @@ -211,12 +213,19 @@ InfinispanPropertiesBuildItem setup(ApplicationArchivesBuildItem applicationArch sslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(Feature.INFINISPAN_CLIENT)); nativeImageSecurityProviders.produce(new NativeImageSecurityProviderBuildItem(SASL_SECURITY_PROVIDER)); + // add per cache file config + handlePerCacheFileConfig(infinispanClientsBuildTimeConfig.defaultInfinispanClient, resourceBuildItem, hotDeployment); + for (InfinispanClientBuildTimeConfig config : infinispanClientsBuildTimeConfig.namedInfinispanClients.values()) { + handlePerCacheFileConfig(config, resourceBuildItem, hotDeployment); + } + Map propertiesMap = new HashMap<>(); IndexView index = applicationIndexBuildItem.getIndex(); // named and default Set allClientNames = infinispanClientNames(applicationIndexBuildItem, infinispanClientNames); allClientNames.addAll(infinispanClientsBuildTimeConfig.getInfinispanNamedClientConfigNames()); + allClientNames.add(DEFAULT_INFINISPAN_CLIENT_NAME); for (String clientName : allClientNames) { Properties properties = loadHotrodProperties(clientName, reflectiveClass, marshallingBuildItem); propertiesMap.put(clientName, properties); @@ -310,6 +319,17 @@ InfinispanPropertiesBuildItem setup(ApplicationArchivesBuildItem applicationArch return new InfinispanPropertiesBuildItem(propertiesMap); } + private void handlePerCacheFileConfig(InfinispanClientBuildTimeConfig config, + BuildProducer resourceBuildItem, + BuildProducer hotDeployment) { + for (InfinispanClientBuildTimeConfig.RemoteCacheConfig cacheConfig : config.cache.values()) { + if (cacheConfig.configurationResource.isPresent()) { + resourceBuildItem.produce(new NativeImageResourceBuildItem(cacheConfig.configurationResource.get())); + hotDeployment.produce(new HotDeploymentWatchedFileBuildItem(cacheConfig.configurationResource.get())); + } + } + } + @BuildStep @Record(ExecutionTime.STATIC_INIT) BeanContainerListenerBuildItem build(InfinispanRecorder recorder, InfinispanPropertiesBuildItem builderBuildItem) { diff --git a/extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/InfinispanConfigurationSetupTest.java b/extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/InfinispanConfigurationSetupTest.java new file mode 100644 index 0000000000000..c6aa1c49e5788 --- /dev/null +++ b/extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/InfinispanConfigurationSetupTest.java @@ -0,0 +1,61 @@ +package org.quarkus.infinispan.client.deployment; + +import static org.assertj.core.api.Assertions.assertThat; + +import jakarta.inject.Inject; + +import org.infinispan.client.hotrod.RemoteCacheManager; +import org.infinispan.client.hotrod.configuration.ClientIntelligence; +import org.infinispan.client.hotrod.configuration.Configuration; +import org.infinispan.client.hotrod.configuration.NearCacheMode; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; + +public class InfinispanConfigurationSetupTest { + @Inject + RemoteCacheManager remoteCacheManager; + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withEmptyApplication() + .withConfigurationResource("cache-config-application.properties") + .withApplicationRoot((jar) -> jar + .addAsResource("distributed-cache-config.xml") + .addAsResource("local-cache-config.xml")); + + @Test + public void infinispanConnectionConfiguration() { + assertThat(remoteCacheManager).isNotNull(); + Configuration configuration = remoteCacheManager.getConfiguration(); + assertThat(configuration.servers().size()).isEqualTo(1); + assertThat(configuration.servers().get(0).host()).isEqualTo("cluster1"); + assertThat(configuration.servers().get(0).port()).isEqualTo(31000); + assertThat(configuration.tracingPropagationEnabled()).isFalse(); + assertThat(configuration.clientIntelligence()).isEqualTo(ClientIntelligence.BASIC); + assertThat(configuration.security().authentication().enabled()).isTrue(); + assertThat(configuration.security().authentication().saslMechanism()).isEqualTo("BASIC"); + assertThat(configuration.security().authentication().serverName()).isEqualTo("custom-server-name"); + assertThat(configuration.security().ssl().enabled()).isTrue(); + assertThat(configuration.security().ssl().trustStorePassword()).isEqualTo("trust-pass".toCharArray()); + assertThat(configuration.security().ssl().trustStoreFileName()).isEqualTo("custom-trust-store"); + assertThat(configuration.security().ssl().trustStoreType()).isEqualTo("JCEKS"); + assertThat(configuration.security().ssl().provider()).isEqualTo("SSL_prov"); + assertThat(configuration.security().ssl().protocol()).isEqualTo("SSL_protocol"); + assertThat(configuration.security().ssl().ciphers()).containsExactlyInAnyOrder("SSL_cipher1", "SSL_cipher2"); + + assertThat(configuration.remoteCaches().get("cache1").configuration()).isEqualTo(""); + assertThat(configuration.remoteCaches().get("cache1").nearCacheBloomFilter()).isTrue(); + assertThat(configuration.remoteCaches().get("cache1").nearCacheMaxEntries()).isEqualTo(100); + assertThat(configuration.remoteCaches().get("cache1").nearCacheMode()).isEqualTo(NearCacheMode.INVALIDATED); + + assertThat(configuration.remoteCaches().get("cache2").configuration()).isEqualTo(""); + assertThat(configuration.remoteCaches().get("cache2").nearCacheBloomFilter()).isFalse(); + assertThat(configuration.remoteCaches().get("cache2").nearCacheMaxEntries()).isEqualTo(-1); + assertThat(configuration.remoteCaches().get("cache2").nearCacheMode()).isEqualTo(NearCacheMode.DISABLED); + + assertThat(configuration.remoteCaches().get("cache3").configuration()).isEqualTo(""); + + } +} diff --git a/extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/InfinispanDefaultMinimalConfigurationTest.java b/extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/InfinispanDefaultMinimalConfigurationTest.java new file mode 100644 index 0000000000000..61003f76eac8d --- /dev/null +++ b/extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/InfinispanDefaultMinimalConfigurationTest.java @@ -0,0 +1,38 @@ +package org.quarkus.infinispan.client.deployment; + +import static org.assertj.core.api.Assertions.assertThat; + +import jakarta.inject.Inject; + +import org.infinispan.client.hotrod.RemoteCacheManager; +import org.infinispan.client.hotrod.configuration.ClientIntelligence; +import org.infinispan.client.hotrod.configuration.Configuration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; + +public class InfinispanDefaultMinimalConfigurationTest { + @Inject + RemoteCacheManager remoteCacheManager; + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withEmptyApplication() + .withConfigurationResource("minimal-application.properties"); + + @Test + public void infinispanConnectionConfiguration() { + assertThat(remoteCacheManager).isNotNull(); + Configuration configuration = remoteCacheManager.getConfiguration(); + assertThat(configuration.servers().size()).isEqualTo(1); + assertThat(configuration.servers().get(0).host()).isEqualTo("cluster1"); + assertThat(configuration.servers().get(0).port()).isEqualTo(31000); + assertThat(configuration.tracingPropagationEnabled()).isTrue(); + assertThat(configuration.clientIntelligence()).isEqualTo(ClientIntelligence.HASH_DISTRIBUTION_AWARE); + assertThat(configuration.remoteCaches()).isEmpty(); + assertThat(configuration.security().authentication().enabled()).isTrue(); + assertThat(configuration.security().authentication().saslMechanism()).isEqualTo("DIGEST-MD5"); + assertThat(configuration.security().ssl().enabled()).isFalse(); + } +} diff --git a/extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/MultipleNamedInfinispanConfigurationSetupTest.java b/extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/MultipleNamedInfinispanConfigurationSetupTest.java new file mode 100644 index 0000000000000..6d62a93844482 --- /dev/null +++ b/extensions/infinispan-client/deployment/src/test/java/org/quarkus/infinispan/client/deployment/MultipleNamedInfinispanConfigurationSetupTest.java @@ -0,0 +1,48 @@ +package org.quarkus.infinispan.client.deployment; + +import static org.assertj.core.api.Assertions.assertThat; + +import jakarta.inject.Inject; + +import org.infinispan.client.hotrod.RemoteCacheManager; +import org.infinispan.client.hotrod.configuration.Configuration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.infinispan.client.InfinispanClientName; +import io.quarkus.test.QuarkusUnitTest; + +public class MultipleNamedInfinispanConfigurationSetupTest { + @Inject + RemoteCacheManager remoteCacheManager; + + @Inject + @InfinispanClientName("another") + RemoteCacheManager anotherRemoteCacheManager; + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withEmptyApplication() + .withConfigurationResource("multiple-cache-config-application.properties") + .withApplicationRoot((jar) -> jar + .addAsResource("distributed-cache-config.xml") + .addAsResource("local-cache-config.xml")); + + @Test + public void infinispanMultipleConnectionsConfiguration() { + assertThat(remoteCacheManager).isNotNull(); + assertThat(anotherRemoteCacheManager).isNotNull(); + + Configuration configuration = remoteCacheManager.getConfiguration(); + assertThat(configuration.servers().size()).isEqualTo(1); + assertThat(configuration.servers().get(0).host()).isEqualTo("cluster1"); + assertThat(configuration.servers().get(0).port()).isEqualTo(31000); + assertThat(configuration.remoteCaches().get("cache3").configuration()).isEqualTo(""); + + Configuration anotherConfiguration = anotherRemoteCacheManager.getConfiguration(); + assertThat(anotherConfiguration.servers().size()).isEqualTo(1); + assertThat(anotherConfiguration.servers().get(0).host()).isEqualTo("cluster2"); + assertThat(anotherConfiguration.servers().get(0).port()).isEqualTo(41000); + assertThat(anotherConfiguration.remoteCaches().get("cache4").configuration()).isEqualTo(""); + } +} diff --git a/extensions/infinispan-client/deployment/src/test/resources/cache-config-application.properties b/extensions/infinispan-client/deployment/src/test/resources/cache-config-application.properties new file mode 100644 index 0000000000000..49238028c1010 --- /dev/null +++ b/extensions/infinispan-client/deployment/src/test/resources/cache-config-application.properties @@ -0,0 +1,33 @@ +# don't run any server with test containers. this config is used to test the configuration mapping +quarkus.infinispan-client.devservices.enabled=false +quarkus.infinispan-client.use-schema-registration=false + +quarkus.infinispan-client.hosts=cluster1:31000 +quarkus.infinispan-client.username=infinispan +quarkus.infinispan-client.password=secret +quarkus.infinispan-client.tracing.propagation.enabled=false +quarkus.infinispan-client.client-intelligence=BASIC +quarkus.infinispan-client.sasl-mechanism=BASIC +quarkus.infinispan-client.auth-realm=infiniRealm +quarkus.infinispan-client.auth-server-name=custom-server-name +quarkus.infinispan-client.trust-store=custom-trust-store +quarkus.infinispan-client.trust-store-password=trust-pass +quarkus.infinispan-client.trust-store-type=JCEKS +quarkus.infinispan-client.ssl-provider=SSL_prov +quarkus.infinispan-client.ssl-protocol=SSL_protocol +quarkus.infinispan-client.ssl-ciphers=SSL_cipher1,SSL_cipher2 + +# cache 1 config +quarkus.infinispan-client.cache.cache1.configuration= +quarkus.infinispan-client.cache.cache1.near-cache-use-bloom-filter=true +quarkus.infinispan-client.cache.cache1.near-cache-max-entries=100 +quarkus.infinispan-client.cache.cache1.near-cache-mode=INVALIDATED + +# cache 2 config (configuration-resource over configuration) +quarkus.infinispan-client.cache.cache2.configuration= +quarkus.infinispan-client.cache.cache2.configuration-resource=distributed-cache-config.xml + +# cache 3 config (configuration-uri over configuration-resource and configuration) +quarkus.infinispan-client.cache.cache3.configuration= +quarkus.infinispan-client.cache.cache3.configuration-resource=distributed-cache-config.xml +quarkus.infinispan-client.cache.cache3.configuration-uri=local-cache-config.xml diff --git a/extensions/infinispan-client/deployment/src/test/resources/distributed-cache-config.xml b/extensions/infinispan-client/deployment/src/test/resources/distributed-cache-config.xml new file mode 100644 index 0000000000000..c1e032bcd9e8d --- /dev/null +++ b/extensions/infinispan-client/deployment/src/test/resources/distributed-cache-config.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extensions/infinispan-client/deployment/src/test/resources/local-cache-config.xml b/extensions/infinispan-client/deployment/src/test/resources/local-cache-config.xml new file mode 100644 index 0000000000000..51ebbe9c2bc0f --- /dev/null +++ b/extensions/infinispan-client/deployment/src/test/resources/local-cache-config.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extensions/infinispan-client/deployment/src/test/resources/minimal-application.properties b/extensions/infinispan-client/deployment/src/test/resources/minimal-application.properties new file mode 100644 index 0000000000000..b496e8226789f --- /dev/null +++ b/extensions/infinispan-client/deployment/src/test/resources/minimal-application.properties @@ -0,0 +1,7 @@ +# don't run any server with test containers. this config is used to test the configuration mapping +quarkus.infinispan-client.devservices.enabled=false +quarkus.infinispan-client.use-schema-registration=false + +quarkus.infinispan-client.hosts=cluster1:31000 +quarkus.infinispan-client.username=infinispan +quarkus.infinispan-client.password=secret \ No newline at end of file diff --git a/extensions/infinispan-client/deployment/src/test/resources/multiple-cache-config-application.properties b/extensions/infinispan-client/deployment/src/test/resources/multiple-cache-config-application.properties new file mode 100644 index 0000000000000..122f879448a43 --- /dev/null +++ b/extensions/infinispan-client/deployment/src/test/resources/multiple-cache-config-application.properties @@ -0,0 +1,20 @@ +# don't run any server with test containers. this config is used to test the configuration mapping +quarkus.infinispan-client.devservices.enabled=false +quarkus.infinispan-client.devservices.another.enabled=false +quarkus.infinispan-client.use-schema-registration=false +quarkus.infinispan-client.another.use-schema-registration=false + +quarkus.infinispan-client.hosts=cluster1:31000 +quarkus.infinispan-client.username=infinispan +quarkus.infinispan-client.password=secret + +quarkus.infinispan-client.another.hosts=cluster2:41000 +quarkus.infinispan-client.another.username=another-infinispan +quarkus.infinispan-client.another.password=another-secret + +# cache 3 config (configuration-uri over configuration-resource and configuration) +quarkus.infinispan-client.cache.cache3.configuration-resource=distributed-cache-config.xml +quarkus.infinispan-client.cache.cache3.configuration-uri=local-cache-config.xml + +# cache 4 config (only present in another and build time config) +quarkus.infinispan-client.another.cache.cache4.configuration-resource=local-cache-config.xml \ No newline at end of file diff --git a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientBuildTimeConfig.java b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientBuildTimeConfig.java index 6f625e0d6ee3b..5ab65898dba2f 100644 --- a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientBuildTimeConfig.java +++ b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientBuildTimeConfig.java @@ -1,5 +1,7 @@ package io.quarkus.infinispan.client.runtime; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -14,8 +16,11 @@ public class InfinispanClientBuildTimeConfig { /** * Sets the bounded entry count for near cache. If this value is 0 or less near cache is disabled. + * + * @deprecated use per cache configuration for near cache max entries */ @ConfigItem + @Deprecated public int nearCacheMaxEntries; /** @@ -24,6 +29,26 @@ public class InfinispanClientBuildTimeConfig { @ConfigItem public Optional marshallerClass; + /** + * Configures caches build time config from the client with the provided configuration. + */ + @ConfigItem + public Map cache = new HashMap<>(); + + @ConfigGroup + public static class RemoteCacheConfig { + + // @formatter:off + /** + * Cache configuration file in XML, JSON or YAML is defined in build time to create the cache on first access. + * An example of the user defined property. cacheConfig.xml file is located in the 'resources' folder: + * quarkus.infinispan-client.cache.bookscache.configuration-resource=cacheConfig.xml + */ + // @formatter:on + @ConfigItem + public Optional configurationResource; + } + /** * Configuration for DevServices. DevServices allows Quarkus to automatically start an Infinispan Server in dev and test * mode. @@ -60,7 +85,7 @@ public int hashCode() { @Override public String toString() { - return "InfinispanClientBuildTimeConfig{" + - "nearCacheMaxEntries=" + nearCacheMaxEntries + '}'; + return "InfinispanClientBuildTimeConfig{" + "nearCacheMaxEntries=" + nearCacheMaxEntries + ", marshallerClass=" + + marshallerClass + ", cache=" + cache + ", devService=" + devService + '}'; } } diff --git a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientProducer.java b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientProducer.java index dbf227a707824..952afe58b1ac4 100644 --- a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientProducer.java +++ b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientProducer.java @@ -5,12 +5,12 @@ import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.stream.Collectors; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Instance; -import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.literal.NamedLiteral; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; @@ -56,6 +56,9 @@ public class InfinispanClientProducer { @Inject private Instance infinispanClientsRuntimeConfigHandle; + @Inject + private Instance infinispanClientsBuildTimeConfigHandle; + private void registerSchemaInServer(String infinispanConfigName, Map properties, RemoteCacheManager cacheManager) { @@ -134,6 +137,9 @@ private ConfigurationBuilder builderFromProperties(String infinispanClientName, InfinispanClientRuntimeConfig infinispanClientRuntimeConfig = infinispanClientsRuntimeConfigHandle.get() .getInfinispanClientRuntimeConfig(infinispanClientName); + InfinispanClientBuildTimeConfig infinispanClientBuildTimeConfig = infinispanClientsBuildTimeConfigHandle.get() + .getInfinispanClientBuildTimeConfig(infinispanClientName); + // client name not found if (infinispanClientRuntimeConfig == null) { return builder; @@ -173,9 +179,6 @@ private ConfigurationBuilder builderFromProperties(String infinispanClientName, } } - properties.put(ConfigurationProperties.TRACING_PROPAGATION_ENABLED, - infinispanClientRuntimeConfig.tracingPropagationEnabled); - if (infinispanClientRuntimeConfig.clientIntelligence.isPresent()) { properties.put(ConfigurationProperties.CLIENT_INTELLIGENCE, infinispanClientRuntimeConfig.clientIntelligence.get()); } @@ -190,13 +193,6 @@ private ConfigurationBuilder builderFromProperties(String infinispanClientName, if (infinispanClientRuntimeConfig.authServerName.isPresent()) { properties.put(ConfigurationProperties.AUTH_SERVER_NAME, infinispanClientRuntimeConfig.authServerName.get()); } - if (infinispanClientRuntimeConfig.authClientSubject.isPresent()) { - properties.put(ConfigurationProperties.AUTH_CLIENT_SUBJECT, infinispanClientRuntimeConfig.authClientSubject.get()); - } - if (infinispanClientRuntimeConfig.authCallbackHandler.isPresent()) { - properties.put(ConfigurationProperties.AUTH_CALLBACK_HANDLER, - infinispanClientRuntimeConfig.authCallbackHandler.get()); - } if (infinispanClientRuntimeConfig.saslMechanism.isPresent()) { properties.put(ConfigurationProperties.SASL_MECHANISM, infinispanClientRuntimeConfig.saslMechanism.get()); @@ -222,43 +218,90 @@ private ConfigurationBuilder builderFromProperties(String infinispanClientName, } if (infinispanClientRuntimeConfig.sslCiphers.isPresent()) { - properties.put(ConfigurationProperties.SSL_CIPHERS, infinispanClientRuntimeConfig.sslCiphers.get().toArray()); + properties.put(ConfigurationProperties.SSL_CIPHERS, + infinispanClientRuntimeConfig.sslCiphers.get().stream().collect(Collectors.joining(" "))); } builder.withProperties(properties); - for (Map.Entry cache : infinispanClientRuntimeConfig.cache + if (infinispanClientRuntimeConfig.tracingPropagationEnabled.isPresent()) { + if (!infinispanClientRuntimeConfig.tracingPropagationEnabled.get()) { + builder.disableTracingPropagation(); + } + } + + if (infinispanClientBuildTimeConfig != null) { + for (Map.Entry buildCacheConfig : infinispanClientBuildTimeConfig.cache + .entrySet()) { + String cacheName = buildCacheConfig.getKey(); + // Do this if the cache config is only present in the build time configuration + if (!infinispanClientRuntimeConfig.cache.containsKey(cacheName)) { + InfinispanClientBuildTimeConfig.RemoteCacheConfig buildCacheConfigValue = buildCacheConfig.getValue(); + if (buildCacheConfig.getValue().configurationResource.isPresent()) { + URL configFile = Thread.currentThread().getContextClassLoader() + .getResource(buildCacheConfigValue.configurationResource.get()); + configureRemoteCacheConfigurationURI(builder, cacheName, configFile); + } + } + } + } + + for (Map.Entry cacheConfig : infinispanClientRuntimeConfig.cache .entrySet()) { - String cacheName = cache.getKey(); - InfinispanClientRuntimeConfig.RemoteCacheConfig remoteCacheConfig = cache.getValue(); - if (remoteCacheConfig.configurationUri.isPresent()) { - String cacheConfigUri = remoteCacheConfig.configurationUri.get(); - log.infof("Configuration URI for cache %s found: %s", cacheName, cacheConfigUri); - URL configFile = Thread.currentThread().getContextClassLoader() - .getResource(cacheConfigUri); - try { - builder.remoteCache(cacheName).configurationURI(configFile.toURI()); - } catch (Exception e) { - - throw new RuntimeException(e); + String cacheName = cacheConfig.getKey(); + InfinispanClientRuntimeConfig.RemoteCacheConfig runtimeCacheConfig = cacheConfig.getValue(); + URL configFile = null; + // Check if the build time resource file configuration exists + if (infinispanClientBuildTimeConfig != null) { + InfinispanClientBuildTimeConfig.RemoteCacheConfig buildtimeCacheConfig = infinispanClientBuildTimeConfig.cache + .get( + cacheName); + if (buildtimeCacheConfig != null && buildtimeCacheConfig.configurationResource.isPresent()) { + configFile = Thread.currentThread().getContextClassLoader() + .getResource(buildtimeCacheConfig.configurationResource.get()); } - } else if (remoteCacheConfig.configuration.isPresent()) { - builder.remoteCache(cacheName).configuration(remoteCacheConfig.configuration.get()); } - if (remoteCacheConfig.nearCacheMaxEntries.isPresent()) { - builder.remoteCache(cacheName).nearCacheMaxEntries(remoteCacheConfig.nearCacheMaxEntries.get()); + + // Override build time resource if configuration-uri runtime resource is provided + if (runtimeCacheConfig.configurationUri.isPresent()) { + configFile = Thread.currentThread().getContextClassLoader() + .getResource(runtimeCacheConfig.configurationUri.get()); } - if (remoteCacheConfig.nearCacheMode.isPresent()) { - builder.remoteCache(cacheName).nearCacheMode(remoteCacheConfig.nearCacheMode.get()); + + if (configFile != null) { + configureRemoteCacheConfigurationURI(builder, cacheName, configFile); + } else { + // Inline configuration + if (runtimeCacheConfig.configuration.isPresent()) { + builder.remoteCache(cacheName).configuration(runtimeCacheConfig.configuration.get()); + } } - if (remoteCacheConfig.nearCacheUseBloomFilter.isPresent()) { - builder.remoteCache(cacheName).nearCacheUseBloomFilter(remoteCacheConfig.nearCacheUseBloomFilter.get()); + + // Configures near caching + if (runtimeCacheConfig.nearCacheMaxEntries.isPresent()) { + builder.remoteCache(cacheName).nearCacheMaxEntries(runtimeCacheConfig.nearCacheMaxEntries.get()); + } + if (runtimeCacheConfig.nearCacheMode.isPresent()) { + builder.remoteCache(cacheName).nearCacheMode(runtimeCacheConfig.nearCacheMode.get()); + } + if (runtimeCacheConfig.nearCacheUseBloomFilter.isPresent()) { + builder.remoteCache(cacheName).nearCacheUseBloomFilter(runtimeCacheConfig.nearCacheUseBloomFilter.get()); } } return builder; } + private void configureRemoteCacheConfigurationURI(ConfigurationBuilder builder, String cacheName, URL configFile) { + try { + builder.remoteCache(cacheName).configurationURI(configFile.toURI()); + } catch (Exception e) { + log.errorf("Provided configuration-resource or configuration-uri can't be loaded. %s", + configFile.getPath()); + throw new IllegalStateException(e); + } + } + private static void handleProtoStreamMarshaller(ProtoStreamMarshaller marshaller, Properties properties, BeanManager beanManager) { SerializationContext serializationContext = marshaller.getSerializationContext(); diff --git a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientRuntimeConfig.java b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientRuntimeConfig.java index beed9c042b4a9..6884512349fff 100644 --- a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientRuntimeConfig.java +++ b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientRuntimeConfig.java @@ -6,8 +6,6 @@ import java.util.Optional; import javax.net.ssl.SSLContext; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; import org.infinispan.client.hotrod.configuration.NearCacheMode; @@ -114,19 +112,6 @@ public class InfinispanClientRuntimeConfig { @ConfigItem(defaultValue = "infinispan") Optional authServerName; - /** - * Sets client subject, necessary for those SASL mechanisms which require it to access client credentials. - */ - @ConfigItem - Optional authClientSubject; - - /** - * Specifies a {@link CallbackHandler} to be used during the authentication handshake. - * The {@link Callback}s that need to be handled are specific to the chosen SASL mechanism. - */ - @ConfigItem - Optional authCallbackHandler; - // @formatter:off /** * Sets SASL mechanism used by authentication. @@ -186,14 +171,14 @@ public class InfinispanClientRuntimeConfig { * Whether a tracing propagation is enabled in case the Opentelemetry extension is present. * By default the propagation of the context is propagated from the client to the Infinispan Server. */ - @ConfigItem(name = "tracing.propagation.enabled", defaultValue = "true") - public boolean tracingPropagationEnabled; + @ConfigItem(name = "tracing.propagation.enabled") + public Optional tracingPropagationEnabled; /** * Configures caches from the client with the provided configuration. */ @ConfigItem - Map cache = new HashMap<>(); + public Map cache = new HashMap<>(); @ConfigGroup public static class RemoteCacheConfig { @@ -211,7 +196,7 @@ public static class RemoteCacheConfig { // @formatter:off /** - * Cache configuration file in XML whose path will be converted to URI to create the cache on first access. + * Cache configuration file in XML, Json or YAML whose path will be converted to URI to create the cache on first access. * An example of the user defined property. cacheConfig.xml file is located in the 'resources' folder: * quarkus.infinispan-client.cache.bookscache.configuration-uri=cacheConfig.xml */ diff --git a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientsBuildTimeConfig.java b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientsBuildTimeConfig.java index c57a79c711e47..d14a2dbc9fd29 100644 --- a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientsBuildTimeConfig.java +++ b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanClientsBuildTimeConfig.java @@ -3,7 +3,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.Map; -import java.util.Objects; import java.util.Set; import io.quarkus.runtime.annotations.ConfigItem; @@ -40,7 +39,6 @@ public InfinispanClientBuildTimeConfig getInfinispanClientBuildTimeConfig(String if (InfinispanClientUtil.isDefault(infinispanClientName)) { return defaultInfinispanClient; } - InfinispanClientBuildTimeConfig infinispanClientBuildTimeConfig = namedInfinispanClients.get(infinispanClientName); - return Objects.requireNonNullElseGet(infinispanClientBuildTimeConfig, InfinispanClientBuildTimeConfig::new); + return namedInfinispanClients.get(infinispanClientName); } } diff --git a/integration-tests/infinispan-client/src/main/resources/application.properties b/integration-tests/infinispan-client/src/main/resources/application.properties index 0b08500be50fd..d9e2391da36e8 100644 --- a/integration-tests/infinispan-client/src/main/resources/application.properties +++ b/integration-tests/infinispan-client/src/main/resources/application.properties @@ -1,5 +1,5 @@ -quarkus.infinispan-client.cache.default.configuration-uri=cacheConfig.xml -quarkus.infinispan-client.cache.books.configuration-uri=booksIndexedConfig.json +quarkus.infinispan-client.cache.default.configuration-resource=cacheConfig.xml +quarkus.infinispan-client.cache.books.configuration-resource=booksIndexedConfig.json quarkus.infinispan-client.cache.magazine.configuration= quarkus.infinispan-client.cache.default.near-cache-mode=INVALIDATED quarkus.infinispan-client.cache.default.near-cache-max-entries=2 @@ -7,7 +7,9 @@ quarkus.infinispan-client.cache.default.near-cache-use-bloom-filter=false quarkus.infinispan-client.cache.magazine.near-cache-mode=INVALIDATED quarkus.infinispan-client.cache.magazine.near-cache-max-entries=2 quarkus.infinispan-client.cache.magazine.near-cache-use-bloom-filter=false -quarkus.native.resources.includes=cacheConfig.xml,booksIndexedConfig.json + +# Have a default cache in another remote infinispan client +quarkus.infinispan-client.another.cache.books.configuration-resource=cacheConfig.xml # Dev services configuration quarkus.infinispan-client.devservices.site=NYC @@ -19,5 +21,3 @@ quarkus.infinispan-client.another.devservices.mcast-port=46667 quarkus.infinispan-client.another.devservices.port=31223 quarkus.infinispan-client.another.devservices.service-name=infinispanAnother -# Have a default cache in another remote infinispan client -quarkus.infinispan-client.another.cache.books.configuration-uri=cacheConfig.xml