Skip to content

Commit f0bbb25

Browse files
committed
[#3106] Allow nested HotRod config keys to be in camel-case.
Also add support for configuring "infinispan.client.hotrod.default_executor_factory.*" HotRod client properties. Signed-off-by: Carsten Lohmann <[email protected]>
1 parent 834f2d1 commit f0bbb25

File tree

6 files changed

+111
-25
lines changed

6 files changed

+111
-25
lines changed

client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/InfinispanRemoteConfigurationOptions.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2021 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation
33
*
44
* See the NOTICE file(s) distributed with this work for additional
55
* information regarding copyright ownership.
@@ -35,6 +35,13 @@ public interface InfinispanRemoteConfigurationOptions {
3535
*/
3636
Map<String, String> connectionPool();
3737

38+
/**
39+
* Gets the default executor factory options.
40+
*
41+
* @return The options.
42+
*/
43+
Map<String, String> defaultExecutorFactory();
44+
3845
/**
3946
* Gets the SASL properties.
4047
*

client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/InfinispanRemoteConfigurationProperties.java

+52-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2020, 2021 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation
33
*
44
* See the NOTICE file(s) distributed with this work for additional
55
* information regarding copyright ownership.
@@ -15,12 +15,13 @@
1515
package org.eclipse.hono.deviceconnection.infinispan.client;
1616

1717
import java.util.Map;
18+
import java.util.Optional;
19+
import java.util.function.Function;
1820

1921
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
2022
import org.infinispan.client.hotrod.impl.ConfigurationProperties;
21-
import org.slf4j.Logger;
22-
import org.slf4j.LoggerFactory;
2323

24+
import com.google.common.base.CaseFormat;
2425
import com.google.common.base.MoreObjects;
2526

2627

@@ -30,7 +31,8 @@
3031
*/
3132
public class InfinispanRemoteConfigurationProperties extends ConfigurationProperties {
3233

33-
private static final Logger LOG = LoggerFactory.getLogger(InfinispanRemoteConfigurationProperties.class);
34+
private static final String DEFAULT_EXECUTOR_FACTORY_PREFIX = "infinispan.client.hotrod.default_executor_factory";
35+
private static final String CONNECTION_POOL_PREFIX = "infinispan.client.hotrod.connection_pool";
3436

3537
/**
3638
* Creates properties using default values.
@@ -57,6 +59,8 @@ public InfinispanRemoteConfigurationProperties(final InfinispanRemoteConfigurati
5759
setConnectionPool(options.connectionPool());
5860
setConnectTimeout(options.connectTimeout());
5961

62+
setDefaultExecutorFactory(options.defaultExecutorFactory());
63+
6064
options.keyAlias().ifPresent(this::setKeyAlias);
6165
options.keyStoreCertificatePassword().ifPresent(this::setKeyStoreCertificatePassword);
6266
options.keyStoreFileName().ifPresent(this::setKeyStoreFileName);
@@ -91,15 +95,24 @@ public final ConfigurationBuilder getConfigurationBuilder() {
9195

9296
/**
9397
* Sets the properties related to the connection pool.
98+
* <p>
99+
* Property keys may be in camel case or snake case.
94100
*
95101
* @param poolProperties The properties.
96102
*/
97103
public final void setConnectionPool(final Map<String, String> poolProperties) {
98-
poolProperties.forEach((k, v) -> {
99-
final String key = String.format("%s.%s", "infinispan.client.hotrod.connection_pool", k);
100-
LOG.debug("setting configuration property [{}: {}]", key, v);
101-
getProperties().setProperty(key, v);
102-
});
104+
setProperties(poolProperties, CONNECTION_POOL_PREFIX, this::toSnakeCase);
105+
}
106+
107+
/**
108+
* Sets the properties related to the default executor factory.
109+
* <p>
110+
* Property keys may be in camel case or snake case.
111+
*
112+
* @param factoryProperties The properties.
113+
*/
114+
public final void setDefaultExecutorFactory(final Map<String, String> factoryProperties) {
115+
setProperties(factoryProperties, DEFAULT_EXECUTOR_FACTORY_PREFIX, this::toSnakeCase);
103116
}
104117

105118
/**
@@ -108,25 +121,45 @@ public final void setConnectionPool(final Map<String, String> poolProperties) {
108121
* @param saslProperties The properties.
109122
*/
110123
public final void setSaslProperties(final Map<String, String> saslProperties) {
111-
saslProperties.forEach((k, v) -> {
112-
final String key = String.format("%s.%s", SASL_PROPERTIES_PREFIX, k);
113-
getProperties().setProperty(key, v);
114-
});
124+
setProperties(saslProperties, SASL_PROPERTIES_PREFIX, null);
115125
}
116126

117127
/**
118128
* Sets the properties related to cluster configuration.
119129
*
120-
* @param cluster The properties.
130+
* @param clusterProperties The properties.
121131
*/
122-
public final void setCluster(final Map<String, String> cluster) {
123-
cluster.forEach((k, v) -> {
124-
final String key = String.format("%s.%s", CLUSTER_PROPERTIES_PREFIX, k);
125-
getProperties().setProperty(key, v);
126-
});
132+
public final void setCluster(final Map<String, String> clusterProperties) {
133+
setProperties(clusterProperties, CLUSTER_PROPERTIES_PREFIX, null);
134+
}
135+
136+
private String toSnakeCase(final String key) {
137+
return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, key);
138+
}
139+
140+
private void setProperties(
141+
final Map<String, String> properties,
142+
final String keyPrefix,
143+
final Function<String, String> keyConverter) {
144+
145+
properties.forEach((k, v) -> {
146+
final String keySuffix = Optional.ofNullable(keyConverter).map(f -> f.apply(k)).orElse(k);
147+
final String key = String.format("%s.%s", keyPrefix, keySuffix);
148+
getProperties().setProperty(key, v);
149+
});
127150
}
128151

129152
// ------- Getters/setters missing in the parent ConfigurationProperties class -------
153+
154+
/**
155+
* Gets the keystore certificate password.
156+
*
157+
* @return The password.
158+
*/
159+
public String getKeyStoreCertificatePassword() {
160+
return getProperties().getProperty(KEY_STORE_CERTIFICATE_PASSWORD);
161+
}
162+
130163
/**
131164
* Gets the SSL ciphers.
132165
*

client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client/InfinispanRemoteConfigurationPropertiesTest.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2020 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation
33
*
44
* See the NOTICE file(s) distributed with this work for additional
55
* information regarding copyright ownership.
@@ -47,4 +47,10 @@ void testConnectionPoolProperties() {
4747
assertThat(config.connectionPool().minEvictableIdleTime()).isGreaterThan(0L);
4848
}
4949

50+
@Test
51+
void testDefaultExecutorFactoryProperties() {
52+
props.setDefaultExecutorFactory(Map.of("pool_size", "50"));
53+
assertThat(props.getDefaultExecutorFactoryPoolSize()).isEqualTo(50);
54+
}
55+
5056
}

client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client/QuarkusPropertyBindingTest.java

+30-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2021 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation
33
*
44
* See the NOTICE file(s) distributed with this work for additional
55
* information regarding copyright ownership.
@@ -16,9 +16,14 @@
1616

1717
import static com.google.common.truth.Truth.assertThat;
1818

19+
import java.util.List;
20+
1921
import javax.inject.Inject;
22+
import javax.security.sasl.Sasl;
2023

21-
import org.infinispan.client.hotrod.impl.ConfigurationProperties;
24+
import org.infinispan.client.hotrod.configuration.ClusterConfiguration;
25+
import org.infinispan.client.hotrod.configuration.Configuration;
26+
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
2227
import org.junit.jupiter.api.Test;
2328

2429
import io.quarkus.test.junit.QuarkusTest;
@@ -52,19 +57,40 @@ void testCommonCacheConfigurationPropertiesArePickedUp() {
5257
void testRemoteCacheConfigurationPropertiesArePickedUp() {
5358
assertThat(remoteCacheOptions).isNotNull();
5459
final var remoteCacheConfig = new InfinispanRemoteConfigurationProperties(remoteCacheOptions);
60+
final Configuration builtRemoteCacheConfig = new ConfigurationBuilder()
61+
.withProperties(remoteCacheConfig.getProperties()).build(false);
62+
5563
assertThat(remoteCacheConfig.getServerList()).contains("data-grid:11222");
5664
assertThat(remoteCacheConfig.getAuthUsername()).isEqualTo("user");
5765
assertThat(remoteCacheConfig.getAuthPassword()).isEqualTo("secret");
5866
assertThat(remoteCacheConfig.getAuthRealm()).isEqualTo("ApplicationRealm");
67+
68+
final List<ClusterConfiguration> clusters = builtRemoteCacheConfig.clusters();
69+
assertThat(clusters.size()).isEqualTo(2);
70+
assertThat(clusters.get(0).getClusterName()).isEqualTo("siteA");
71+
assertThat(clusters.get(0).getCluster().size()).isEqualTo(2);
72+
assertThat(clusters.get(0).getCluster().get(0).host()).isEqualTo("hostA1");
73+
assertThat(clusters.get(0).getCluster().get(0).port()).isEqualTo(11222);
74+
assertThat(clusters.get(1).getClusterName()).isEqualTo("siteB");
75+
76+
assertThat(remoteCacheConfig.gtConnectionPoolMinIdle()).isEqualTo(10);
77+
assertThat(remoteCacheConfig.getConnectionPoolMaxActive()).isEqualTo(10);
78+
assertThat(remoteCacheConfig.getConnectionPoolMaxPendingRequests()).isEqualTo(400);
79+
assertThat(remoteCacheConfig.getConnectionPoolMaxWait()).isEqualTo(500);
80+
81+
assertThat(remoteCacheConfig.getDefaultExecutorFactoryPoolSize()).isEqualTo(200);
82+
5983
assertThat(remoteCacheConfig.getSaslMechanism()).contains("DIGEST-MD5");
84+
final var saslProperties = builtRemoteCacheConfig.security().authentication().saslProperties();
85+
assertThat(saslProperties.get(Sasl.QOP)).isEqualTo("auth");
86+
6087
assertThat(remoteCacheConfig.getSoTimeout()).isEqualTo(5000);
6188
assertThat(remoteCacheConfig.getConnectTimeout()).isEqualTo(5000);
6289
assertThat(remoteCacheConfig.getKeyStoreFileName()).isEqualTo("/etc/hono/key-store.p12");
6390
assertThat(remoteCacheConfig.getKeyStoreType()).isEqualTo("PKCS12");
6491
assertThat(remoteCacheConfig.getKeyStorePassword()).isEqualTo("key-store-secret");
6592
assertThat(remoteCacheConfig.getKeyAlias()).isEqualTo("infinispan");
66-
assertThat(remoteCacheConfig.getProperties().getProperty(ConfigurationProperties.KEY_STORE_CERTIFICATE_PASSWORD))
67-
.isEqualTo("cert-secret");
93+
assertThat(remoteCacheConfig.getKeyStoreCertificatePassword()).isEqualTo("cert-secret");
6894
assertThat(remoteCacheConfig.getTrustStoreFileName()).isEqualTo("/etc/hono/trust-store-file.p12");
6995
assertThat(remoteCacheConfig.getTrustStorePath()).isEqualTo("/etc/hono/trust-store.p12");
7096
assertThat(remoteCacheConfig.getTrustStoreType()).isEqualTo("PKCS12");

client-device-connection-infinispan/src/test/resources/application.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,19 @@ hono:
1010
authUsername: "user"
1111
authPassword: "secret"
1212
authRealm: "ApplicationRealm"
13+
cluster:
14+
siteA: "hostA1:11222; hostA2:11223"
15+
siteB: "hostB1:11222; hostB2:11223"
16+
connectionPool:
17+
minIdle: 10
18+
maxActive: 10
19+
maxPendingRequests: 400
20+
maxWait: 500
21+
defaultExecutorFactory:
22+
poolSize: 200
1323
saslMechanism: "DIGEST-MD5"
24+
saslProperties:
25+
"javax.security.sasl.qop": "auth"
1426
socketTimeout: 5000
1527
connectTimeout: 5000
1628
keyStoreFileName: "/etc/hono/key-store.p12"

site/homepage/content/release-notes.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ description = "Information about changes in recent Hono releases. Includes new f
1313
*hono.mongodb.connectionString* property. This has been fixed.
1414
* Using OpenSSL with the Quarkus based variant of Hono components did not work as described in the Secure Communication
1515
guide. This has been fixed.
16+
* The connection pool configuration for the HotRod client in the Quarkus variant of the Command Router component
17+
didn't support using property names in camel-case. This has been fixed.
1618

1719
## 1.12.0
1820

0 commit comments

Comments
 (0)