Skip to content

Commit

Permalink
Merge 0423590 into d4644da
Browse files Browse the repository at this point in the history
  • Loading branch information
sazzad16 authored Feb 15, 2023
2 parents d4644da + 0423590 commit 47aeba3
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 58 deletions.
5 changes: 0 additions & 5 deletions src/main/java/redis/clients/jedis/BuilderFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,12 @@
import java.util.*;
import java.util.stream.Collectors;

import redis.clients.jedis.exceptions.JedisException;
import redis.clients.jedis.resps.StreamConsumerFullInfo;
import redis.clients.jedis.resps.StreamFullInfo;
import redis.clients.jedis.resps.StreamGroupFullInfo;
import redis.clients.jedis.resps.LCSMatchResult.MatchedPosition;
import redis.clients.jedis.resps.LCSMatchResult.Position;
import redis.clients.jedis.resps.*;
import redis.clients.jedis.search.aggr.AggregationResult;
import redis.clients.jedis.timeseries.TSKeyedElements;
import redis.clients.jedis.timeseries.TSElement;
import redis.clients.jedis.timeseries.TSKeyValue;
import redis.clients.jedis.util.DoublePrecision;
import redis.clients.jedis.util.JedisByteHashMap;
import redis.clients.jedis.util.KeyValue;
Expand Down
65 changes: 50 additions & 15 deletions src/main/java/redis/clients/jedis/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.args.Rawable;
import redis.clients.jedis.commands.ProtocolCommand;
Expand Down Expand Up @@ -341,23 +343,34 @@ private void initializeFromClientConfig(JedisClientConfig config) {
try {
connect();

Supplier<RedisCredentials> credentialsProvider = config.getCredentialsProvider();
if (credentialsProvider instanceof RedisCredentialsProvider) {
((RedisCredentialsProvider) credentialsProvider).prepare();
auth(credentialsProvider);
((RedisCredentialsProvider) credentialsProvider).cleanUp();
if (config.getRedisProtocol() == RedisProtocol.RESP3 && config.getUser() != null) {

hello(config.getRedisProtocol(), config.getUser(), config.getPassword(), config.getClientName());

} else {
auth(credentialsProvider);
}

int dbIndex = config.getDatabase();
if (dbIndex > 0) {
select(dbIndex);
}
String clientName = config.getClientName();
if (clientName != null) {
// TODO: need to figure out something without encoding
clientSetname(clientName);
Supplier<RedisCredentials> credentialsProvider = config.getCredentialsProvider();
if (credentialsProvider instanceof RedisCredentialsProvider) {
((RedisCredentialsProvider) credentialsProvider).prepare();
auth(credentialsProvider);
((RedisCredentialsProvider) credentialsProvider).cleanUp();
} else {
auth(credentialsProvider);
}

int dbIndex = config.getDatabase();
if (dbIndex > 0) {
select(dbIndex);
}
String clientName = config.getClientName();
if (clientName != null) {
// TODO: need to figure out something without encoding
clientSetname(clientName);
}

if (config.getRedisProtocol() != null) {
hello(config.getRedisProtocol());
}
}

} catch (JedisException je) {
Expand All @@ -373,6 +386,28 @@ private void initializeFromClientConfig(JedisClientConfig config) {
}
}

private Map hello(final RedisProtocol protocol) {
sendCommand(Protocol.Command.HELLO, String.valueOf(protocol.version()));
Map reply = BuilderFactory.ENCODED_OBJECT_MAP.build(getOne());
LoggerFactory.getLogger(Connection.class).info("HELLO reply: {}", reply);
return reply;
}

private Map hello(final RedisProtocol protocol, final String user, final String password,
final String clientName) {
if (clientName == null) {
sendCommand(Protocol.Command.HELLO, String.valueOf(protocol.version()),
Protocol.Keyword.AUTH.name(), user, password);
} else {
sendCommand(Protocol.Command.HELLO, String.valueOf(protocol.version()),
Protocol.Keyword.AUTH.name(), user, password,
Protocol.Keyword.SETNAME.name(), clientName);
}
Map reply = BuilderFactory.ENCODED_OBJECT_MAP.build(getOne());
LoggerFactory.getLogger(Connection.class).info("HELLO reply: {}", reply);
return reply;
}

private void auth(final Supplier<RedisCredentials> credentialsProvider) {
RedisCredentials credentials = credentialsProvider.get();
if (credentials == null || credentials.getPassword() == null) return;
Expand Down
23 changes: 19 additions & 4 deletions src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

public final class DefaultJedisClientConfig implements JedisClientConfig {

private final RedisProtocol redisProtocol;

private final int connectionTimeoutMillis;
private final int socketTimeoutMillis;
private final int blockingSocketTimeoutMillis;
Expand All @@ -22,10 +24,11 @@ public final class DefaultJedisClientConfig implements JedisClientConfig {

private final HostAndPortMapper hostAndPortMapper;

private DefaultJedisClientConfig(int connectionTimeoutMillis, int soTimeoutMillis,
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) {
this.redisProtocol = protocol;
this.connectionTimeoutMillis = connectionTimeoutMillis;
this.socketTimeoutMillis = soTimeoutMillis;
this.blockingSocketTimeoutMillis = blockingSocketTimeoutMillis;
Expand All @@ -39,6 +42,11 @@ private DefaultJedisClientConfig(int connectionTimeoutMillis, int soTimeoutMilli
this.hostAndPortMapper = hostAndPortMapper;
}

@Override
public RedisProtocol getRedisProtocol() {
return redisProtocol;
}

@Override
public int getConnectionTimeoutMillis() {
return connectionTimeoutMillis;
Expand Down Expand Up @@ -118,6 +126,8 @@ public static Builder builder() {

public static class Builder {

private RedisProtocol redisProtocol = null;

private int connectionTimeoutMillis = Protocol.DEFAULT_TIMEOUT;
private int socketTimeoutMillis = Protocol.DEFAULT_TIMEOUT;
private int blockingSocketTimeoutMillis = 0;
Expand All @@ -144,11 +154,16 @@ public DefaultJedisClientConfig build() {
new DefaultRedisCredentials(user, password));
}

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

public Builder protocol(RedisProtocol protocol) {
this.redisProtocol = protocol;
return this;
}

public Builder timeoutMillis(int timeoutMillis) {
this.connectionTimeoutMillis = timeoutMillis;
this.socketTimeoutMillis = timeoutMillis;
Expand Down Expand Up @@ -230,15 +245,15 @@ public static DefaultJedisClientConfig create(int connectionTimeoutMillis, int s
int blockingSocketTimeoutMillis, String user, String password, int database, String clientName,
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
HostnameVerifier hostnameVerifier, HostAndPortMapper hostAndPortMapper) {
return new DefaultJedisClientConfig(
return new DefaultJedisClientConfig(null,
connectionTimeoutMillis, soTimeoutMillis, blockingSocketTimeoutMillis,
new DefaultRedisCredentialsProvider(new DefaultRedisCredentials(user, password)),
database, clientName, ssl, sslSocketFactory, sslParameters,
hostnameVerifier, hostAndPortMapper);
}

public static DefaultJedisClientConfig copyConfig(JedisClientConfig copy) {
return new DefaultJedisClientConfig(copy.getConnectionTimeoutMillis(),
return new DefaultJedisClientConfig(null, copy.getConnectionTimeoutMillis(),
copy.getSocketTimeoutMillis(), copy.getBlockingSocketTimeoutMillis(),
copy.getCredentialsProvider(), copy.getDatabase(), copy.getClientName(),
copy.isSsl(), copy.getSslSocketFactory(), copy.getSslParameters(),
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/redis/clients/jedis/JedisClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

public interface JedisClientConfig {

default RedisProtocol getRedisProtocol() {
return null;
}

/**
* @return Connection timeout in milliseconds
*/
Expand Down
88 changes: 54 additions & 34 deletions src/main/java/redis/clients/jedis/Protocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,18 @@ public final class Protocol {

public static final Charset CHARSET = StandardCharsets.UTF_8;

public static final byte DOLLAR_BYTE = '$';
public static final byte ASTERISK_BYTE = '*';
public static final byte PLUS_BYTE = '+';
public static final byte MINUS_BYTE = '-';
public static final byte COLON_BYTE = ':';
public static final byte COMMA_BYTE = ',';
public static final byte DOLLAR_BYTE = '$';
public static final byte EQUAL_BYTE = '=';
public static final byte HASH_BYTE = '#';
public static final byte LEFT_BRACE_BYTE = '(';
public static final byte MINUS_BYTE = '-';
public static final byte PERCENT_BYTE = '%';
public static final byte PLUS_BYTE = '+';
public static final byte TILDE_BYTE = '~';
public static final byte UNDERSCORE_BYTE = '_';

public static final byte[] BYTES_TRUE = toByteArray(1);
public static final byte[] BYTES_FALSE = toByteArray(0);
Expand Down Expand Up @@ -124,27 +131,42 @@ private static String[] parseTargetHostAndSlot(String clusterRedirectResponse) {

private static Object process(final RedisInputStream is) {
final byte b = is.readByte();
int num;
switch (b) {
case PLUS_BYTE:
return processStatusCodeReply(is);
return is.readLineBytes();
case DOLLAR_BYTE:
case EQUAL_BYTE:
return processBulkReply(is);
case ASTERISK_BYTE:
return processMultiBulkReply(is);
num = is.readIntCrLf();
if (num == -1) return null;
return processMultiBulkReply(num, is);
case COLON_BYTE:
return processInteger(is);
return is.readLongCrLf();
case UNDERSCORE_BYTE:
return is.readNullCrLf();
case COMMA_BYTE:
return is.readDoubleCrLf();
case LEFT_BRACE_BYTE:
return is.readBigIntegerCrLf();
case PERCENT_BYTE: // TODO: currently just to start working with HELLO
num = is.readIntCrLf();
if (num == -1) return null;
return processMultiBulkReply(2 * num, is);
case TILDE_BYTE: // TODO:
num = is.readIntCrLf();
if (num == -1) return null;
return processMultiBulkReply(num, is);
case MINUS_BYTE:
processError(is);
return null;
// TODO: Blob error '!'
default:
throw new JedisConnectionException("Unknown reply: " + (char) b);
}
}

private static byte[] processStatusCodeReply(final RedisInputStream is) {
return is.readLineBytes();
}

private static byte[] processBulkReply(final RedisInputStream is) {
final int len = is.readIntCrLf();
if (len == -1) {
Expand All @@ -168,15 +190,9 @@ private static byte[] processBulkReply(final RedisInputStream is) {
return read;
}

private static Long processInteger(final RedisInputStream is) {
return is.readLongCrLf();
}

private static List<Object> processMultiBulkReply(final RedisInputStream is) {
final int num = is.readIntCrLf();
if (num == -1) {
return null;
}
// private static List<Object> processMultiBulkReply(final RedisInputStream is) {
private static List<Object> processMultiBulkReply(final int num, final RedisInputStream is) {
// final int num = is.readIntCrLf();
final List<Object> ret = new ArrayList<>(num);
for (int i = 0; i < num; i++) {
try {
Expand Down Expand Up @@ -216,28 +232,32 @@ public static final byte[] toByteArray(final double value) {

public static enum Command implements ProtocolCommand {

PING, SET, GET, GETDEL, GETEX, QUIT, EXISTS, DEL, UNLINK, TYPE, FLUSHDB, KEYS, RANDOMKEY, MOVE,
RENAME, RENAMENX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, FLUSHALL, GETSET, MGET, SETNX, SETEX,
MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET,
HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, HRANDFIELD, HINCRBYFLOAT, HSTRLEN, MIGRATE,
PING, AUTH, HELLO, SET, GET, GETDEL, GETEX, QUIT, EXISTS, DEL, UNLINK, TYPE, FLUSHDB, FLUSHALL,
KEYS, RANDOMKEY, MOVE, RENAME, RENAMENX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, GETSET, MGET,
SETNX, SETEX, MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, STRLEN, APPEND, SUBSTR, MIGRATE, ECHO, //
HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, HSTRLEN,
HRANDFIELD, HINCRBYFLOAT, // <-- hash
RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP, BLPOP, BRPOP, LINSERT, LPOS,
RPOPLPUSH, BRPOPLPUSH, BLMOVE, LMOVE, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SRANDMEMBER,
SINTER, SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SISMEMBER, SMISMEMBER, SINTERCARD,
MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, SORT_RO, AUTH, INFO, SHUTDOWN, MONITOR, CONFIG, LCS,
SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, STRLEN, LPUSHX, RPUSHX, ECHO,
RPOPLPUSH, BRPOPLPUSH, BLMOVE, LMOVE, LMPOP, BLMPOP, // <-- list
SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SRANDMEMBER, SINTER, SINTERSTORE, SUNION, SUNIONSTORE,
SDIFF, SDIFFSTORE, SISMEMBER, SMISMEMBER, SINTERCARD, // <-- set
MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, SORT_RO, INFO, SHUTDOWN, MONITOR, CONFIG, LCS,
SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, LPUSHX, RPUSHX, //
ZADD, ZDIFF, ZDIFFSTORE, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK, ZREVRANGE, ZRANDMEMBER, ZCARD,
ZSCORE, ZPOPMAX, ZPOPMIN, ZCOUNT, ZUNION, ZUNIONSTORE, ZINTER, ZINTERSTORE, ZRANGEBYSCORE,
ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZLEXCOUNT, ZRANGEBYLEX, ZREVRANGEBYLEX,
ZREMRANGEBYLEX, ZMSCORE, ZRANGESTORE, ZINTERCARD, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, PERSIST,
ZREMRANGEBYLEX, ZMSCORE, ZRANGESTORE, ZINTERCARD, ZMPOP, BZMPOP, // <-- zset
GEOADD, GEODIST, GEOHASH, GEOPOS, GEORADIUS, GEORADIUS_RO, GEOSEARCH, GEOSEARCHSTORE,
GEORADIUSBYMEMBER, GEORADIUSBYMEMBER_RO, // <-- geo
XADD, XLEN, XDEL, XTRIM, XRANGE, XREVRANGE, XREAD, XACK, XGROUP, XREADGROUP, XPENDING, XCLAIM,
XAUTOCLAIM, XINFO, // <-- stream
SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, PERSIST, BITFIELD_RO, ROLE, FAILOVER, EVAL_RO, EVALSHA_RO,
SETBIT, GETBIT, BITPOS, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG, OBJECT, BITCOUNT,
BITOP, SENTINEL, DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT, PSETEX, CLIENT, TIME,
SCAN, HSCAN, SSCAN, ZSCAN, WAIT, CLUSTER, ASKING, READONLY, READWRITE, SLAVEOF, REPLICAOF, COPY,
PFADD, PFCOUNT, PFMERGE, MODULE, ACL, GEOADD, GEODIST, GEOHASH, GEOPOS, GEORADIUS, GEORADIUS_RO,
GEORADIUSBYMEMBER, GEORADIUSBYMEMBER_RO, BITFIELD, TOUCH, SWAPDB, MEMORY, BZPOPMIN, BZPOPMAX,
XADD, XLEN, XDEL, XTRIM, XRANGE, XREVRANGE, XREAD, XACK, XGROUP, XREADGROUP, XPENDING, XCLAIM,
XAUTOCLAIM, XINFO, BITFIELD_RO, ROLE, FAILOVER, GEOSEARCH, GEOSEARCHSTORE, EVAL_RO, EVALSHA_RO,
LOLWUT, EXPIRETIME, PEXPIRETIME, FUNCTION, FCALL, FCALL_RO, LMPOP, BLMPOP, ZMPOP, BZMPOP,
COMMAND, LATENCY, @Deprecated STRALGO;
PFADD, PFCOUNT, PFMERGE, MODULE, ACL, BITFIELD, TOUCH, SWAPDB, MEMORY, BZPOPMIN, BZPOPMAX,
LOLWUT, EXPIRETIME, PEXPIRETIME, FUNCTION, FCALL, FCALL_RO, COMMAND, LATENCY,
@Deprecated STRALGO;

private final byte[] raw;

Expand Down
17 changes: 17 additions & 0 deletions src/main/java/redis/clients/jedis/RedisProtocol.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package redis.clients.jedis;

public enum RedisProtocol {

RESP2(2),
RESP3(3);

private final int version;

private RedisProtocol(int version) {
this.version = version;
}

public int version() {
return version;
}
}
Loading

0 comments on commit 47aeba3

Please sign in to comment.