Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend CLIENT SETINFO support #3509

Merged
merged 9 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -388,7 +388,7 @@ private static boolean validateClientInfo(String info) {
return true;
}

private void initializeFromClientConfig(JedisClientConfig config) {
private void initializeFromClientConfig(final JedisClientConfig config) {
try {
connect();

Expand All @@ -415,16 +415,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() { };

if (!setInfoConfig.isDisabled()) {
String libName = JedisMetaInfo.getArtifactId();
sazzad16 marked this conversation as resolved.
Show resolved Hide resolved
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));
String libVersion = JedisMetaInfo.getVersion();
sazzad16 marked this conversation as resolved.
Show resolved Hide resolved
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;
}
}
}
25 changes: 21 additions & 4 deletions src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ public final class DefaultJedisClientConfig implements JedisClientConfig {

private final HostAndPortMapper hostAndPortMapper;

private final ClientSetInfoConfig clientSetInfoConfig;

private DefaultJedisClientConfig(RedisProtocol protocol, 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.redisProtocol = protocol;
this.connectionTimeoutMillis = connectionTimeoutMillis;
this.socketTimeoutMillis = soTimeoutMillis;
Expand All @@ -40,6 +43,7 @@ private DefaultJedisClientConfig(RedisProtocol protocol, int connectionTimeoutMi
this.sslParameters = sslParameters;
this.hostnameVerifier = hostnameVerifier;
this.hostAndPortMapper = hostAndPortMapper;
this.clientSetInfoConfig = clientSetInfoConfig;
}

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

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

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

private HostAndPortMapper hostAndPortMapper = null;

private ClientSetInfoConfig clientSetInfoConfig = null;

private Builder() {
}

Expand All @@ -149,7 +160,7 @@ public DefaultJedisClientConfig build() {

return new DefaultJedisClientConfig(redisProtocol, connectionTimeoutMillis, socketTimeoutMillis,
blockingSocketTimeoutMillis, credentialsProvider, database, clientName, ssl,
sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper);
sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper, clientSetInfoConfig);
}

/**
Expand Down Expand Up @@ -239,6 +250,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 @@ -248,14 +264,15 @@ public static DefaultJedisClientConfig create(int connectionTimeoutMillis, int s
return new DefaultJedisClientConfig(null,
connectionTimeoutMillis, soTimeoutMillis, blockingSocketTimeoutMillis,
new DefaultRedisCredentialsProvider(new DefaultRedisCredentials(user, password)), database,
clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper);
clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper, null);
}

public static DefaultJedisClientConfig copyConfig(JedisClientConfig copy) {
return new DefaultJedisClientConfig(copy.getRedisProtocol(),
copy.getConnectionTimeoutMillis(), copy.getSocketTimeoutMillis(),
copy.getBlockingSocketTimeoutMillis(), copy.getCredentialsProvider(),
copy.getDatabase(), copy.getClientName(), copy.isSsl(), copy.getSslSocketFactory(),
copy.getSslParameters(), copy.getHostnameVerifier(), copy.getHostAndPortMapper());
copy.getSslParameters(), 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 @@ -288,4 +289,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
Loading