diff --git a/pom.xml b/pom.xml
index a5d3a47ec6..29392c4c73 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-redis
- 2.5.0-SNAPSHOT
+ 2.5.0-GH-1957-SNAPSHOT
Spring Data Redis
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterListCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterListCommands.java
index 78722fe4de..20f0b44b9e 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterListCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterListCommands.java
@@ -15,12 +15,13 @@
*/
package org.springframework.data.redis.connection.jedis;
+import redis.clients.jedis.params.LPosParams;
+
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.springframework.dao.DataAccessException;
-import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.ClusterSlotHashUtil;
import org.springframework.data.redis.connection.RedisListCommands;
import org.springframework.data.redis.connection.jedis.JedisClusterConnection.JedisMultiKeyClusterCommandCallback;
@@ -68,7 +69,22 @@ public List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Null
Assert.notNull(key, "Key must not be null!");
Assert.notNull(element, "Element must not be null!");
- throw new InvalidDataAccessApiUsageException("LPOS is not supported by jedis.");
+ LPosParams params = new LPosParams();
+ if (rank != null) {
+ params.rank(rank);
+ }
+
+ try {
+
+ if (count != null) {
+ return connection.getCluster().lpos(key, element, params, count);
+ }
+
+ Long value = connection.getCluster().lpos(key, element, params);
+ return value != null ? Collections.singletonList(value) : Collections.emptyList();
+ } catch (Exception ex) {
+ throw convertJedisAccessException(ex);
+ }
}
/*
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java
index fcf540e67b..66b4d41197 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java
@@ -19,12 +19,14 @@
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.Protocol;
+import java.util.Collections;
import java.util.List;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.RedisListCommands;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
+import redis.clients.jedis.params.LPosParams;
/**
* @author Christoph Strobl
@@ -61,7 +63,16 @@ public List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Null
Assert.notNull(key, "Key must not be null!");
Assert.notNull(element, "Element must not be null!");
- throw new InvalidDataAccessApiUsageException("LPOS is not supported by jedis.");
+ LPosParams params = new LPosParams();
+ if(rank != null) {
+ params.rank(rank);
+ }
+
+ if(count != null) {
+ return connection.invoke().just(BinaryJedis::lpos, MultiKeyPipelineBase::lpos, key, element, params, count);
+ }
+
+ return connection.invoke().from(BinaryJedis::lpos, MultiKeyPipelineBase::lpos, key, element, params).getOrElse(Collections::singletonList, Collections::emptyList);
}
/*
diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceListCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceListCommands.java
index 8c3500772c..459f0f6252 100644
--- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceListCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceListCommands.java
@@ -71,7 +71,7 @@ public List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Null
return connection.invoke().just(RedisListAsyncCommands::lpos, key, element, count, args);
}
- return connection.invoke().from(RedisListAsyncCommands::lpos, key, element, args).get(Collections::singletonList);
+ return connection.invoke().from(RedisListAsyncCommands::lpos, key, element, args).getOrElse(Collections::singletonList, Collections::emptyList);
}
/*
diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java
index dc4b1e0045..8e01f681b2 100644
--- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java
@@ -1404,9 +1404,8 @@ void testLPushMultiple() {
verifyResults(Arrays.asList(2L, Arrays.asList("baz", "bar")));
}
- @Test // DATAREDIS-1196
+ @Test // DATAREDIS-1196, GH-1957
@EnabledOnCommand("LPOS")
- @EnabledOnRedisDriver({ RedisDriver.LETTUCE })
void lPos() {
actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c"));
@@ -1415,9 +1414,8 @@ void lPos() {
assertThat((List) getResults().get(1)).containsOnly(2L);
}
- @Test // DATAREDIS-1196
+ @Test // DATAREDIS-1196, GH-1957
@EnabledOnCommand("LPOS")
- @EnabledOnRedisDriver({ RedisDriver.LETTUCE })
void lPosRank() {
actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c"));
@@ -1426,9 +1424,8 @@ void lPosRank() {
assertThat((List) getResults().get(1)).containsExactly(6L);
}
- @Test // DATAREDIS-1196
+ @Test // DATAREDIS-1196, GH-1957
@EnabledOnCommand("LPOS")
- @EnabledOnRedisDriver({ RedisDriver.LETTUCE })
void lPosNegativeRank() {
actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c"));
@@ -1437,9 +1434,8 @@ void lPosNegativeRank() {
assertThat((List) getResults().get(1)).containsExactly(7L);
}
- @Test // DATAREDIS-1196
+ @Test // DATAREDIS-1196, GH-1957
@EnabledOnCommand("LPOS")
- @EnabledOnRedisDriver({ RedisDriver.LETTUCE })
void lPosCount() {
actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c"));
@@ -1448,9 +1444,8 @@ void lPosCount() {
assertThat((List) getResults().get(1)).containsExactly(2L, 6L);
}
- @Test // DATAREDIS-1196
+ @Test // DATAREDIS-1196, GH-1957
@EnabledOnCommand("LPOS")
- @EnabledOnRedisDriver({ RedisDriver.LETTUCE })
void lPosRankCount() {
actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c"));
@@ -1459,9 +1454,8 @@ void lPosRankCount() {
assertThat((List) getResults().get(1)).containsExactly(7L, 6L);
}
- @Test // DATAREDIS-1196
+ @Test // DATAREDIS-1196, GH-1957
@EnabledOnCommand("LPOS")
- @EnabledOnRedisDriver({ RedisDriver.LETTUCE })
void lPosCountZero() {
actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c"));
@@ -1470,6 +1464,16 @@ void lPosCountZero() {
assertThat((List) getResults().get(1)).containsExactly(2L, 6L, 7L);
}
+ @Test // GH-1957
+ @EnabledOnCommand("LPOS")
+ void lPosNonExisting() {
+
+ actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c"));
+ actual.add(connection.lPos("mylist", "x", null, null));
+
+ assertThat((List) getResults().get(1)).isEmpty();
+ }
+
// Set operations
@Test
diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java
index 6ffcd6b090..7029daaa19 100644
--- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java
@@ -25,6 +25,7 @@
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*;
import static org.springframework.data.redis.core.ScanOptions.*;
+import org.springframework.data.redis.test.condition.EnabledOnCommand;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
@@ -32,6 +33,7 @@
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
@@ -2472,4 +2474,74 @@ void evelShaShouldRunScript() {
Long result = clusterConnection.scriptingCommands().evalSha(digest, ReturnType.VALUE, 1, keyAndArgs);
assertThat(result).isEqualTo(1L);
}
+
+ @Test // GH-1957
+ @EnabledOnCommand("LPOS")
+ void lPos() {
+
+ nativeConnection.rpush(KEY_1, "a", "b", "c", "1", "2", "3", "c", "c");
+ List result = clusterConnection.listCommands().lPos(KEY_1_BYTES, "c".getBytes(StandardCharsets.UTF_8), null, null);
+
+ assertThat(result).containsOnly(2L);
+ }
+
+ @Test // GH-1957
+ @EnabledOnCommand("LPOS")
+ void lPosRank() {
+
+ nativeConnection.rpush(KEY_1, "a", "b", "c", "1", "2", "3", "c", "c");
+ List result = clusterConnection.listCommands().lPos(KEY_1_BYTES, "c".getBytes(StandardCharsets.UTF_8), 2, null);
+
+ assertThat(result).containsExactly(6L);
+ }
+
+ @Test // GH-1957
+ @EnabledOnCommand("LPOS")
+ void lPosNegativeRank() {
+
+ nativeConnection.rpush(KEY_1, "a", "b", "c", "1", "2", "3", "c", "c");
+ List result = clusterConnection.listCommands().lPos(KEY_1_BYTES, "c".getBytes(StandardCharsets.UTF_8), -1, null);
+
+ assertThat(result).containsExactly(7L);
+ }
+
+ @Test // GH-1957
+ @EnabledOnCommand("LPOS")
+ void lPosCount() {
+
+ nativeConnection.rpush(KEY_1, "a", "b", "c", "1", "2", "3", "c", "c");
+ List result = clusterConnection.listCommands().lPos(KEY_1_BYTES, "c".getBytes(StandardCharsets.UTF_8), null, 2);
+
+ assertThat(result).containsExactly(2L, 6L);
+ }
+
+ @Test // GH-1957
+ @EnabledOnCommand("LPOS")
+ void lPosRankCount() {
+
+ nativeConnection.rpush(KEY_1, "a", "b", "c", "1", "2", "3", "c", "c");
+ List result = clusterConnection.listCommands().lPos(KEY_1_BYTES, "c".getBytes(StandardCharsets.UTF_8), -1, 2);
+
+ assertThat(result).containsExactly(7L, 6L);
+ }
+
+ @Test // GH-1957
+ @EnabledOnCommand("LPOS")
+ void lPosCountZero() {
+
+ nativeConnection.rpush(KEY_1, "a", "b", "c", "1", "2", "3", "c", "c");
+ List result = clusterConnection.listCommands().lPos(KEY_1_BYTES, "c".getBytes(StandardCharsets.UTF_8), null, 0);
+
+ assertThat(result).containsExactly(2L, 6L, 7L);
+ }
+
+ @Test // GH-1957
+ @EnabledOnCommand("LPOS")
+ void lPosNonExisting() {
+
+ nativeConnection.rpush(KEY_1, "a", "b", "c", "1", "2", "3", "c", "c");
+ List result = clusterConnection.listCommands().lPos(KEY_1_BYTES, "x".getBytes(StandardCharsets.UTF_8), null, null);
+
+ assertThat(result).isEmpty();
+ }
}