Skip to content

Commit

Permalink
Extend CLIENT SETINFO support (#3509)
Browse files Browse the repository at this point in the history
* Extend CLIENT SETINFO support

* Modify JedisMetaInfo

* Fix custom lib name and ver

* Remove version suffix

* Separate ClientSetInfoConfig

* Address braces

* Rename method to isDisabled
  • Loading branch information
sazzad16 committed Sep 14, 2023
1 parent 3d45faf commit 59cc560
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 50 deletions.
18 changes: 18 additions & 0 deletions src/main/java/redis/clients/jedis/ClientSetInfoConfig.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
29 changes: 19 additions & 10 deletions src/main/java/redis/clients/jedis/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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) {
Expand Down
62 changes: 62 additions & 0 deletions src/main/java/redis/clients/jedis/DefaultClientSetInfoConfig.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
27 changes: 22 additions & 5 deletions src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<RedisCredentials> 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;
Expand All @@ -37,6 +40,7 @@ private DefaultJedisClientConfig(int connectionTimeoutMillis, int soTimeoutMilli
this.sslParameters = sslParameters;
this.hostnameVerifier = hostnameVerifier;
this.hostAndPortMapper = hostAndPortMapper;
this.clientSetInfoConfig = clientSetInfoConfig;
}

@Override
Expand Down Expand Up @@ -112,6 +116,11 @@ public HostAndPortMapper getHostAndPortMapper() {
return hostAndPortMapper;
}

@Override
public ClientSetInfoConfig getClientSetInfoConfig() {
return clientSetInfoConfig;
}

public static Builder builder() {
return new Builder();
}
Expand All @@ -135,6 +144,8 @@ public static class Builder {

private HostAndPortMapper hostAndPortMapper = null;

private ClientSetInfoConfig clientSetInfoConfig = null;

private Builder() {
}

Expand All @@ -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) {
Expand Down Expand Up @@ -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,
Expand All @@ -233,15 +249,16 @@ 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) {
return new DefaultJedisClientConfig(copy.getConnectionTimeoutMillis(),
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());
}
}
7 changes: 7 additions & 0 deletions src/main/java/redis/clients/jedis/JedisClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
56 changes: 25 additions & 31 deletions src/main/java/redis/clients/jedis/util/JedisMetaInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
39 changes: 39 additions & 0 deletions src/test/java/redis/clients/jedis/JedisTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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()));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 59cc560

Please sign in to comment.