From 59cc560fb2c6d3d504674fbc59f00d762eec5c7a Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Wed, 13 Sep 2023 13:56:54 +0600 Subject: [PATCH] Extend CLIENT SETINFO support (#3509) * Extend CLIENT SETINFO support * Modify JedisMetaInfo * Fix custom lib name and ver * Remove version suffix * Separate ClientSetInfoConfig * Address braces * Rename method to isDisabled --- .../clients/jedis/ClientSetInfoConfig.java | 18 ++++++ .../java/redis/clients/jedis/Connection.java | 29 ++++++--- .../jedis/DefaultClientSetInfoConfig.java | 62 +++++++++++++++++++ .../jedis/DefaultJedisClientConfig.java | 27 ++++++-- .../clients/jedis/JedisClientConfig.java | 7 +++ .../clients/jedis/util/JedisMetaInfo.java | 56 ++++++++--------- .../java/redis/clients/jedis/JedisTest.java | 39 ++++++++++++ .../commands/jedis/ClientCommandsTest.java | 8 +-- 8 files changed, 196 insertions(+), 50 deletions(-) create mode 100644 src/main/java/redis/clients/jedis/ClientSetInfoConfig.java create mode 100644 src/main/java/redis/clients/jedis/DefaultClientSetInfoConfig.java diff --git a/src/main/java/redis/clients/jedis/ClientSetInfoConfig.java b/src/main/java/redis/clients/jedis/ClientSetInfoConfig.java new file mode 100644 index 0000000000..257c17d73d --- /dev/null +++ b/src/main/java/redis/clients/jedis/ClientSetInfoConfig.java @@ -0,0 +1,18 @@ +package redis.clients.jedis; + +/** + * This interface is to modify the behavior of internally executing CLIENT SETINFO command. + */ +public interface ClientSetInfoConfig { + + default boolean isDisabled() { + return false; + } + + /** + * If provided, this suffix will be enclosed by braces {@code ()}. + */ + default String getLibNameSuffix() { + return null; + } +} diff --git a/src/main/java/redis/clients/jedis/Connection.java b/src/main/java/redis/clients/jedis/Connection.java index efa7d21cbe..2e08a17d84 100644 --- a/src/main/java/redis/clients/jedis/Connection.java +++ b/src/main/java/redis/clients/jedis/Connection.java @@ -369,7 +369,7 @@ private static boolean validateClientInfo(String info) { return true; } - private void initializeFromClientConfig(JedisClientConfig config) { + private void initializeFromClientConfig(final JedisClientConfig config) { try { connect(); @@ -397,16 +397,25 @@ private void initializeFromClientConfig(JedisClientConfig config) { fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETNAME).add(clientName)); } - String libName = JedisMetaInfo.getArtifactId(); - if (libName != null && validateClientInfo(libName)) { - fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETINFO) - .add(ClientAttributeOption.LIB_NAME.getRaw()).add(libName)); - } + ClientSetInfoConfig setInfoConfig = config.getClientSetInfoConfig(); + if (setInfoConfig == null) setInfoConfig = new ClientSetInfoConfig() { }; - String libVersion = JedisMetaInfo.getVersion(); - if (libVersion != null && validateClientInfo(libVersion)) { - fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETINFO) - .add(ClientAttributeOption.LIB_VER.getRaw()).add(libVersion)); + if (!setInfoConfig.isDisabled()) { + String libName = JedisMetaInfo.getArtifactId(); + if (libName != null && validateClientInfo(libName)) { + String libNameSuffix = setInfoConfig.getLibNameSuffix(); + if (libNameSuffix != null && validateClientInfo(libNameSuffix)) { + libName = libName + '(' + libNameSuffix + ')'; + } + fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETINFO) + .add(ClientAttributeOption.LIB_NAME.getRaw()).add(libName)); + } + + String libVersion = JedisMetaInfo.getVersion(); + if (libVersion != null && validateClientInfo(libVersion)) { + fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETINFO) + .add(ClientAttributeOption.LIB_VER.getRaw()).add(libVersion)); + } } for (CommandArguments arg : fireAndForgetMsg) { diff --git a/src/main/java/redis/clients/jedis/DefaultClientSetInfoConfig.java b/src/main/java/redis/clients/jedis/DefaultClientSetInfoConfig.java new file mode 100644 index 0000000000..c2f0298cb1 --- /dev/null +++ b/src/main/java/redis/clients/jedis/DefaultClientSetInfoConfig.java @@ -0,0 +1,62 @@ +package redis.clients.jedis; + +public final class DefaultClientSetInfoConfig implements ClientSetInfoConfig { + + private final boolean disabled; + + private final String libNameSuffix; + + private DefaultClientSetInfoConfig(boolean disabled, String libNameSuffix) { + this.disabled = disabled; + this.libNameSuffix = libNameSuffix; + } + + @Override + public boolean isDisabled() { + return disabled; + } + + @Override + public String getLibNameSuffix() { + return libNameSuffix; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private boolean disable = false; + + private String libNameSuffix = null; + + private Builder() { + } + + public DefaultClientSetInfoConfig build() { + if (disable) { + if (libNameSuffix != null) { + throw new IllegalArgumentException("libNameSuffix cannot be used when internal " + + "CLIENT SETINFO command is disabled."); + } + } + + return new DefaultClientSetInfoConfig(disable, libNameSuffix); + } + + public Builder disable() { + return disable(true); + } + + public Builder disable(boolean disable) { + this.disable = disable; + return this; + } + + public Builder libNameSuffix(String suffix) { + this.libNameSuffix = suffix; + return this; + } + } +} diff --git a/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java b/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java index db7f8500e8..74cf5c6605 100644 --- a/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java +++ b/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java @@ -22,10 +22,13 @@ public final class DefaultJedisClientConfig implements JedisClientConfig { private final HostAndPortMapper hostAndPortMapper; + private final ClientSetInfoConfig clientSetInfoConfig; + private DefaultJedisClientConfig(int connectionTimeoutMillis, int soTimeoutMillis, int blockingSocketTimeoutMillis, Supplier credentialsProvider, int database, String clientName, boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters, - HostnameVerifier hostnameVerifier, HostAndPortMapper hostAndPortMapper) { + HostnameVerifier hostnameVerifier, HostAndPortMapper hostAndPortMapper, + ClientSetInfoConfig clientSetInfoConfig) { this.connectionTimeoutMillis = connectionTimeoutMillis; this.socketTimeoutMillis = soTimeoutMillis; this.blockingSocketTimeoutMillis = blockingSocketTimeoutMillis; @@ -37,6 +40,7 @@ private DefaultJedisClientConfig(int connectionTimeoutMillis, int soTimeoutMilli this.sslParameters = sslParameters; this.hostnameVerifier = hostnameVerifier; this.hostAndPortMapper = hostAndPortMapper; + this.clientSetInfoConfig = clientSetInfoConfig; } @Override @@ -112,6 +116,11 @@ public HostAndPortMapper getHostAndPortMapper() { return hostAndPortMapper; } + @Override + public ClientSetInfoConfig getClientSetInfoConfig() { + return clientSetInfoConfig; + } + public static Builder builder() { return new Builder(); } @@ -135,6 +144,8 @@ public static class Builder { private HostAndPortMapper hostAndPortMapper = null; + private ClientSetInfoConfig clientSetInfoConfig = null; + private Builder() { } @@ -146,7 +157,7 @@ public DefaultJedisClientConfig build() { return new DefaultJedisClientConfig(connectionTimeoutMillis, socketTimeoutMillis, blockingSocketTimeoutMillis, credentialsProvider, database, clientName, ssl, - sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper); + sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper, clientSetInfoConfig); } public Builder timeoutMillis(int timeoutMillis) { @@ -224,6 +235,11 @@ public Builder hostAndPortMapper(HostAndPortMapper hostAndPortMapper) { this.hostAndPortMapper = hostAndPortMapper; return this; } + + public Builder clientSetInfoConfig(ClientSetInfoConfig setInfoConfig) { + this.clientSetInfoConfig = setInfoConfig; + return this; + } } public static DefaultJedisClientConfig create(int connectionTimeoutMillis, int soTimeoutMillis, @@ -233,8 +249,8 @@ public static DefaultJedisClientConfig create(int connectionTimeoutMillis, int s return new DefaultJedisClientConfig( connectionTimeoutMillis, soTimeoutMillis, blockingSocketTimeoutMillis, new DefaultRedisCredentialsProvider(new DefaultRedisCredentials(user, password)), - database, clientName, ssl, sslSocketFactory, sslParameters, - hostnameVerifier, hostAndPortMapper); + database, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, + hostAndPortMapper, null); } public static DefaultJedisClientConfig copyConfig(JedisClientConfig copy) { @@ -242,6 +258,7 @@ public static DefaultJedisClientConfig copyConfig(JedisClientConfig copy) { copy.getSocketTimeoutMillis(), copy.getBlockingSocketTimeoutMillis(), copy.getCredentialsProvider(), copy.getDatabase(), copy.getClientName(), copy.isSsl(), copy.getSslSocketFactory(), copy.getSslParameters(), - copy.getHostnameVerifier(), copy.getHostAndPortMapper()); + copy.getHostnameVerifier(), copy.getHostAndPortMapper(), + copy.getClientSetInfoConfig()); } } diff --git a/src/main/java/redis/clients/jedis/JedisClientConfig.java b/src/main/java/redis/clients/jedis/JedisClientConfig.java index ad3febbfb6..cb7701bcb0 100644 --- a/src/main/java/redis/clients/jedis/JedisClientConfig.java +++ b/src/main/java/redis/clients/jedis/JedisClientConfig.java @@ -80,4 +80,11 @@ default HostAndPortMapper getHostAndPortMapper() { return null; } + /** + * Modify the behavior of internally executing CLIENT SETINFO command. + * @return CLIENT SETINFO config + */ + default ClientSetInfoConfig getClientSetInfoConfig() { + return null; + } } diff --git a/src/main/java/redis/clients/jedis/util/JedisMetaInfo.java b/src/main/java/redis/clients/jedis/util/JedisMetaInfo.java index c8c6566c4a..0025f3a522 100644 --- a/src/main/java/redis/clients/jedis/util/JedisMetaInfo.java +++ b/src/main/java/redis/clients/jedis/util/JedisMetaInfo.java @@ -2,45 +2,39 @@ import java.io.InputStream; import java.util.Properties; - -import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Jedis Meta info load version groupId */ public class JedisMetaInfo { - private static final Logger log = LoggerFactory.getLogger(JedisMetaInfo.class); - - private static String groupId; - private static String artifactId; - private static String version; - - static { - Properties p = new Properties(); - try { - InputStream in = JedisMetaInfo.class.getClassLoader().getResourceAsStream("pom.properties"); - p.load(in); - - groupId = p.getProperty("groupId", null); - artifactId = p.getProperty("artifactId", null); - version = p.getProperty("version", null); - - in.close(); - } catch (Exception e) { - log.error("Load Jedis meta info from pom.properties failed", e); - } - } - public static String getGroupId() { - return groupId; - } + private static final String groupId; + private static final String artifactId; + private static final String version; - public static String getArtifactId() { - return artifactId; + static { + Properties p = new Properties(); + try (InputStream in = JedisMetaInfo.class.getClassLoader().getResourceAsStream("pom.properties")) { + p.load(in); + } catch (Exception e) { + LoggerFactory.getLogger(JedisMetaInfo.class).error("Load Jedis meta info from pom.properties failed", e); } - public static String getVersion() { - return version; - } + groupId = p.getProperty("groupId", null); + artifactId = p.getProperty("artifactId", null); + version = p.getProperty("version", null); + } + + public static String getGroupId() { + return groupId; + } + + public static String getArtifactId() { + return artifactId; + } + + public static String getVersion() { + return version; + } } diff --git a/src/test/java/redis/clients/jedis/JedisTest.java b/src/test/java/redis/clients/jedis/JedisTest.java index 76bcbebf54..d430b8ca27 100644 --- a/src/test/java/redis/clients/jedis/JedisTest.java +++ b/src/test/java/redis/clients/jedis/JedisTest.java @@ -22,6 +22,7 @@ import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.commands.jedis.JedisCommandsTestBase; +import redis.clients.jedis.util.JedisMetaInfo; import redis.clients.jedis.util.SafeEncoder; public class JedisTest extends JedisCommandsTestBase { @@ -236,4 +237,42 @@ public void checkDisconnectOnQuit() { assertFalse(jedis.isConnected()); } + @Test + public void clientSetInfoDefault() { + try (Jedis jedis = new Jedis(hnp, DefaultJedisClientConfig.builder().password("foobared") + .build())) { + assertEquals("PONG", jedis.ping()); + String info = jedis.clientInfo(); + assertTrue(info.contains("lib-name=" + JedisMetaInfo.getArtifactId())); + assertTrue(info.contains("lib-ver=" + JedisMetaInfo.getVersion())); + } + } + + @Test + public void clientSetInfoDisable() { + try (Jedis jedis = new Jedis(hnp, DefaultJedisClientConfig.builder().password("foobared") + .clientSetInfoConfig(new ClientSetInfoConfig() { + @Override public boolean isDisabled() { return true; } + }).build())) { + assertEquals("PONG", jedis.ping()); + String info = jedis.clientInfo(); + assertFalse(info.contains("lib-name=" + JedisMetaInfo.getArtifactId())); + assertFalse(info.contains("lib-ver=" + JedisMetaInfo.getVersion())); + } + } + + @Test + public void clientSetInfoCustom() { + final String libNameSuffix = "for-redis"; + ClientSetInfoConfig setInfoConfig = DefaultClientSetInfoConfig.builder() + .libNameSuffix(libNameSuffix).build(); + try (Jedis jedis = new Jedis(hnp, DefaultJedisClientConfig.builder().password("foobared") + .clientSetInfoConfig(setInfoConfig).build())) { + assertEquals("PONG", jedis.ping()); + String info = jedis.clientInfo(); + assertTrue(info.contains("lib-name=" + JedisMetaInfo.getArtifactId() + '(' + libNameSuffix + ')')); + assertTrue(info.contains("lib-ver=" + JedisMetaInfo.getVersion())); + } + } + } diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java index cbe04a5503..8c3f35db49 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java @@ -64,14 +64,14 @@ public void nameBinary() { } @Test - public void clientSetInfoDefault() { - String libName = "jedis"; + public void clientSetInfoCommand() { + String libName = "Jedis::A-Redis-Java-library"; String libVersion = "999.999.999"; assertEquals("OK", client.clientSetInfo(ClientAttributeOption.LIB_NAME, libName)); assertEquals("OK", client.clientSetInfo(ClientAttributeOption.LIB_VER, libVersion)); String info = client.clientInfo(); - assertTrue(info.contains("lib-name=jedis")); - assertTrue(info.contains("lib-ver=999.999.999")); + assertTrue(info.contains("lib-name=" + libName)); + assertTrue(info.contains("lib-ver=" + libVersion)); } @Test