GEODE-8794: Support redis 6 HELLO command (#5856)
- This deals with some specfics related to how the lettuce v6 client
determines what protocol to use when authentication is also enabled.
Co-authored-by: Sarah <sabbey@pivotal.io>
diff --git a/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/connection/AuthIntegrationTest.java b/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/connection/AuthIntegrationTest.java
index 14393e5..f7c8cad 100644
--- a/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/connection/AuthIntegrationTest.java
+++ b/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/connection/AuthIntegrationTest.java
@@ -20,6 +20,8 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import io.lettuce.core.RedisClient;
+import io.lettuce.core.RedisURI;
import org.junit.After;
import org.junit.Test;
import redis.clients.jedis.Jedis;
@@ -137,4 +139,25 @@
authorizedJedis.close();
nonAuthorizedJedis.close();
}
+
+ @Test
+ public void lettuceAuthClient_withLettuceVersion6() {
+ setupCacheWithPassword();
+
+ RedisURI uri = RedisURI.create(String.format("redis://%s@localhost:%d", PASSWORD, getPort()));
+ RedisClient client = RedisClient.create(uri);
+
+ client.connect().sync().ping();
+ }
+
+ @Test
+ public void lettuceAuthClient_withLettuceVersion6_andNoAuthentication() {
+ setupCacheWithoutPassword();
+
+ RedisURI uri = RedisURI.create(String.format("redis://%s@localhost:%d", PASSWORD, getPort()));
+ RedisClient client = RedisClient.create(uri);
+
+ assertThatThrownBy(() -> client.connect().sync().ping())
+ .hasRootCauseMessage("ERR Client sent AUTH, but no password is set");
+ }
}
diff --git a/geode-redis/src/main/java/org/apache/geode/redis/internal/RedisCommandSupportLevel.java b/geode-redis/src/main/java/org/apache/geode/redis/internal/RedisCommandSupportLevel.java
index bdfd81f..3971e31 100644
--- a/geode-redis/src/main/java/org/apache/geode/redis/internal/RedisCommandSupportLevel.java
+++ b/geode-redis/src/main/java/org/apache/geode/redis/internal/RedisCommandSupportLevel.java
@@ -19,5 +19,6 @@
public enum RedisCommandSupportLevel {
SUPPORTED,
UNSUPPORTED,
- UNIMPLEMENTED
+ UNIMPLEMENTED,
+ UNKNOWN
}
diff --git a/geode-redis/src/main/java/org/apache/geode/redis/internal/RedisCommandType.java b/geode-redis/src/main/java/org/apache/geode/redis/internal/RedisCommandType.java
index b2aa735..0bf44cd 100755
--- a/geode-redis/src/main/java/org/apache/geode/redis/internal/RedisCommandType.java
+++ b/geode-redis/src/main/java/org/apache/geode/redis/internal/RedisCommandType.java
@@ -174,8 +174,6 @@
PUNSUBSCRIBE(new PunsubscribeExecutor(), SUPPORTED, new MinimumParameterRequirements(1)),
UNSUBSCRIBE(new UnsubscribeExecutor(), SUPPORTED, new MinimumParameterRequirements(1)),
- UNKNOWN(new UnknownExecutor(), SUPPORTED),
-
/***************************************
*** Unsupported Commands ***
***************************************/
@@ -379,7 +377,12 @@
ZREVRANK(null, UNIMPLEMENTED),
ZSCORE(null, UNIMPLEMENTED),
ZUNIONSCORE(null, UNIMPLEMENTED),
- ZSCAN(null, UNIMPLEMENTED);
+ ZSCAN(null, UNIMPLEMENTED),
+
+ /***************************************
+ *** Unknown Commands ***
+ ***************************************/
+ UNKNOWN(new UnknownExecutor(), RedisCommandSupportLevel.UNKNOWN);
private final Executor executor;
private final ParameterRequirements parameterRequirements;
@@ -416,6 +419,10 @@
return supportLevel == UNIMPLEMENTED;
}
+ public boolean isUnknown() {
+ return supportLevel == RedisCommandSupportLevel.UNKNOWN;
+ }
+
public boolean isAllowedWhileSubscribed() {
switch (this) {
case SUBSCRIBE:
diff --git a/geode-redis/src/main/java/org/apache/geode/redis/internal/netty/Command.java b/geode-redis/src/main/java/org/apache/geode/redis/internal/netty/Command.java
index 1be6134..6aa154b 100755
--- a/geode-redis/src/main/java/org/apache/geode/redis/internal/netty/Command.java
+++ b/geode-redis/src/main/java/org/apache/geode/redis/internal/netty/Command.java
@@ -80,6 +80,10 @@
return commandType.isUnimplemented();
}
+ public boolean isUnknown() {
+ return commandType.isUnknown();
+ }
+
/**
* Used to get the command element list
*
diff --git a/geode-redis/src/main/java/org/apache/geode/redis/internal/netty/ExecutionHandlerContext.java b/geode-redis/src/main/java/org/apache/geode/redis/internal/netty/ExecutionHandlerContext.java
index de3ba83..68e3811 100644
--- a/geode-redis/src/main/java/org/apache/geode/redis/internal/netty/ExecutionHandlerContext.java
+++ b/geode-redis/src/main/java/org/apache/geode/redis/internal/netty/ExecutionHandlerContext.java
@@ -281,6 +281,11 @@
channel.remoteAddress().toString());
}
+ if (command.isUnknown()) {
+ writeToChannel(command.execute(this));
+ return;
+ }
+
if (!isAuthenticated()) {
writeToChannel(handleUnAuthenticatedCommand(command));
return;
diff --git a/geode-redis/src/test/java/org/apache/geode/redis/internal/SupportedCommandsJUnitTest.java b/geode-redis/src/test/java/org/apache/geode/redis/internal/SupportedCommandsJUnitTest.java
index fa2872e..a6bd34f 100644
--- a/geode-redis/src/test/java/org/apache/geode/redis/internal/SupportedCommandsJUnitTest.java
+++ b/geode-redis/src/test/java/org/apache/geode/redis/internal/SupportedCommandsJUnitTest.java
@@ -58,7 +58,6 @@
"SUBSCRIBE",
"TTL",
"TYPE",
- "UNKNOWN",
"UNSUBSCRIBE",
};
@@ -231,6 +230,10 @@
"ZSCAN"
};
+ private final String[] unknownCommands = new String[] {
+ "UNKNOWN"
+ };
+
@Test
public void crossCheckAllUnsupportedCommands_areMarkedUnsupported() {
for (String commandName : unSupportedCommands) {
@@ -278,8 +281,9 @@
List<String> allCommands = new ArrayList<>(asList(supportedCommands));
allCommands.addAll(asList(unSupportedCommands));
- List<String> implementedCommands =
- getAllImplementedCommands().stream().map(Enum::name).collect(Collectors.toList());
+ List<String> implementedCommands = getAllImplementedCommands().stream()
+ .filter(c -> !c.isUnknown())
+ .map(Enum::name).collect(Collectors.toList());
assertThat(implementedCommands).containsExactlyInAnyOrderElementsOf(allCommands);
}
@@ -289,6 +293,7 @@
List<String> allCommands = new ArrayList<>(asList(supportedCommands));
allCommands.addAll(asList(unSupportedCommands));
allCommands.addAll(asList(unImplementedCommands));
+ allCommands.addAll(asList(unknownCommands));
List<String> definedCommands =
Arrays.stream(RedisCommandType.values()).map(Enum::name).collect(Collectors.toList());