committed by
Mark Paluch
parent
c6ba95f271
commit
06f35914c5
@@ -865,22 +865,52 @@ public interface ReactiveHashCommands {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExpireCommand}.
|
||||
*
|
||||
* @param fields the {@code field} names to apply expiration to
|
||||
* @param timeout the actual timeout
|
||||
* @param unit the unit of measure for the {@code timeout}.
|
||||
* @return new instance of {@link ExpireCommand}.
|
||||
*/
|
||||
public static ExpireCommand expire(List<ByteBuffer> fields, long timeout, TimeUnit unit) {
|
||||
|
||||
Assert.notNull(fields, "Field must not be null");
|
||||
return expire(fields, Expiration.from(timeout, unit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExpireCommand}.
|
||||
*
|
||||
* @param fields the {@code field} names to apply expiration to.
|
||||
* @param ttl the actual timeout.
|
||||
* @return new instance of {@link ExpireCommand}.
|
||||
*/
|
||||
public static ExpireCommand expire(List<ByteBuffer> fields, Duration ttl) {
|
||||
|
||||
Assert.notNull(fields, "Field must not be null");
|
||||
return expire(fields, Expiration.from(ttl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExpireCommand}.
|
||||
*
|
||||
* @param fields the {@code field} names to apply expiration to
|
||||
* @param expiration the {@link Expiration} to apply to the given {@literal fields}.
|
||||
* @return new instance of {@link ExpireCommand}.
|
||||
*/
|
||||
public static ExpireCommand expire(List<ByteBuffer> fields, Expiration expiration) {
|
||||
return new ExpireCommand(null, fields, expiration, FieldExpirationOptions.none());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExpireCommand}.
|
||||
*
|
||||
* @param fields the {@code field} names to apply expiration to
|
||||
* @param ttl the unix point in time when to expire the given {@literal fields}.
|
||||
* @param precision can be {@link TimeUnit#SECONDS} or {@link TimeUnit#MILLISECONDS}.
|
||||
* @return new instance of {@link ExpireCommand}.
|
||||
*/
|
||||
public static ExpireCommand expireAt(List<ByteBuffer> fields, Instant ttl, TimeUnit precision) {
|
||||
|
||||
if (precision.compareTo(TimeUnit.MILLISECONDS) > 0) {
|
||||
@@ -890,10 +920,18 @@ public interface ReactiveHashCommands {
|
||||
return expire(fields, Expiration.unixTimestamp(ttl.toEpochMilli(), TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key the {@literal key} from which to expire the {@literal fields} from.
|
||||
* @return new instance of {@link ExpireCommand}.
|
||||
*/
|
||||
public ExpireCommand from(ByteBuffer key) {
|
||||
return new ExpireCommand(key, getFields(), expiration, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param options additional options to be sent along with the command.
|
||||
* @return new instance of {@link ExpireCommand}.
|
||||
*/
|
||||
public ExpireCommand withOptions(FieldExpirationOptions options) {
|
||||
return new ExpireCommand(getKey(), getFields(), getExpiration(), options);
|
||||
}
|
||||
|
||||
@@ -255,11 +255,34 @@ public interface RedisHashCommands {
|
||||
@Nullable
|
||||
Long hStrLen(byte[] key, byte[] field);
|
||||
|
||||
/**
|
||||
* Apply a given {@link org.springframework.data.redis.core.types.Expiration} to the given {@literal fields}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param expiration the {@link org.springframework.data.redis.core.types.Expiration} to apply.
|
||||
* @param fields the names of the {@literal fields} to apply the {@literal expiration} to.
|
||||
* @return a {@link List} holding the command result for each field in order - {@code 2} indicating the specific field
|
||||
* is deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration
|
||||
* time is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating there is no
|
||||
* such field;
|
||||
* @since 3.5
|
||||
*/
|
||||
default @Nullable List<Long> applyExpiration(byte[] key,
|
||||
org.springframework.data.redis.core.types.Expiration expiration, byte[]... fields) {
|
||||
return applyExpiration(key, expiration, FieldExpirationOptions.none(), fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key must not be {@literal null}.
|
||||
* @param expiration the {@link org.springframework.data.redis.core.types.Expiration} to apply.
|
||||
* @param options additional options to be sent along with the command.
|
||||
* @param fields the names of the {@literal fields} to apply the {@literal expiration} to.
|
||||
* @return a {@link List} holding the command result for each field in order - {@code 2} indicating the specific field
|
||||
* is deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration
|
||||
* time is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX | GT | LT
|
||||
* condition is not met); {@code -2} indicating there is no such field;
|
||||
* @since 3.5
|
||||
*/
|
||||
@Nullable
|
||||
default List<Long> applyExpiration(byte[] key, org.springframework.data.redis.core.types.Expiration expiration,
|
||||
FieldExpirationOptions options, byte[]... fields) {
|
||||
@@ -304,9 +327,8 @@ public interface RedisHashCommands {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration time
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX | GT | LT condition
|
||||
* is not met); {@code -2} indicating there is no such field; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating there is no such
|
||||
* field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpire/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -324,9 +346,8 @@ public interface RedisHashCommands {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration time
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX | GT | LT condition
|
||||
* is not met); {@code -2} indicating there is no such field; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating there is no such
|
||||
* field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpire/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -362,9 +383,8 @@ public interface RedisHashCommands {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration time
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX | GT | LT condition
|
||||
* is not met); {@code -2} indicating there is no such field; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set ; {@code -2} indicating there is no
|
||||
* such field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hpexpire/">Redis Documentation: HPEXPIRE</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -382,9 +402,8 @@ public interface RedisHashCommands {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration time
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX | GT | LT condition
|
||||
* is not met); {@code -2} indicating there is no such field; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating there is no such
|
||||
* field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hpexpire/">Redis Documentation: HPEXPIRE</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -420,9 +439,8 @@ public interface RedisHashCommands {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is in the past; {@code 1} indicating
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX |
|
||||
* GT | LT condition is not met); {@code -2} indicating there is no such field; {@literal null} when used in
|
||||
* pipeline / transaction.
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating
|
||||
* there is no such field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpireat/">Redis Documentation: HEXPIREAT</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -457,9 +475,8 @@ public interface RedisHashCommands {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is in the past; {@code 1} indicating
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX |
|
||||
* GT | LT condition is not met); {@code -2} indicating there is no such field; {@literal null} when used in
|
||||
* pipeline / transaction.
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating
|
||||
* there is no such field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hpexpireat/">Redis Documentation: HPEXPIREAT</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -531,8 +548,6 @@ public interface RedisHashCommands {
|
||||
* @since 3.5
|
||||
*/
|
||||
@Nullable
|
||||
// TODO: this is complete nonsense as it would jeopardize negative values
|
||||
// TODO: this should be a List<Map.Entry<byte, Expiration>>
|
||||
List<Long> hTtl(byte[] key, TimeUnit timeUnit, byte[]... fields);
|
||||
|
||||
/**
|
||||
|
||||
@@ -2341,9 +2341,8 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration time
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX | GT | LT condition
|
||||
* is not met); {@code -2} indicating there is no such field; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating there is no such
|
||||
* field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpire/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -2377,9 +2376,8 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration time
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX | GT | LT condition
|
||||
* is not met); {@code -2} indicating there is no such field; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating there is no such
|
||||
* field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hpexpire/">Redis Documentation: HPEXPIRE</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -2413,9 +2411,8 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is in the past; {@code 1} indicating
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX |
|
||||
* GT | LT condition is not met); {@code -2} indicating there is no such field; {@literal null} when used in
|
||||
* pipeline / transaction.
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating
|
||||
* there is no such field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpireat/">Redis Documentation: HEXPIREAT</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -2449,9 +2446,8 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
* @param fields must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is in the past; {@code 1} indicating
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX |
|
||||
* GT | LT condition is not met); {@code -2} indicating there is no such field; {@literal null} when used in
|
||||
* pipeline / transaction.
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set; {@code -2} indicating
|
||||
* there is no such field; {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hpexpireat/">Redis Documentation: HPEXPIREAT</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
|
||||
@@ -34,33 +34,30 @@ import org.springframework.lang.Nullable;
|
||||
public interface BoundHashFieldExpirationOperations<HK> {
|
||||
|
||||
/**
|
||||
* Apply {@link Expiration} to the hash without any additional constraints.
|
||||
* Apply {@link Expiration} to the bound hash key/hash fields without any additional constraints.
|
||||
*
|
||||
* @param expiration the expiration definition.
|
||||
* @return changes to the hash fields.
|
||||
* @return changes to the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
*/
|
||||
default ExpireChanges<HK> expire(Expiration expiration) {
|
||||
return expire(expiration, Hash.FieldExpirationOptions.none());
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply {@link Expiration} to the hash fields given {@link Hash.FieldExpirationOptions expiration options}.
|
||||
* Apply {@link Expiration} to the bound hash key/hash fields given {@link Hash.FieldExpirationOptions expiration
|
||||
* options}.
|
||||
*
|
||||
* @param expiration the expiration definition.
|
||||
* @param options expiration options.
|
||||
* @return changes to the hash fields.
|
||||
* @return changes to the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
*/
|
||||
ExpireChanges<HK> expire(Expiration expiration, Hash.FieldExpirationOptions options);
|
||||
|
||||
/**
|
||||
* Set time to live for given {@code hashKey}.
|
||||
* Set time to live for the bound hash key/hash fields.
|
||||
*
|
||||
* @param timeout the amount of time after which the key will be expired, must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration time
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX | GT | LT condition
|
||||
* is not met); {@code -2} indicating there is no such field; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* @return changes to the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @throws IllegalArgumentException if the timeout is {@literal null}.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpire/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
@@ -69,14 +66,10 @@ public interface BoundHashFieldExpirationOperations<HK> {
|
||||
ExpireChanges<HK> expire(Duration timeout);
|
||||
|
||||
/**
|
||||
* Set the expiration for given {@code hashKey} as a {@literal date} timestamp.
|
||||
* Set the expiration for the bound hash key/hash fields as a {@literal date} timestamp.
|
||||
*
|
||||
* @param expireAt must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is in the past; {@code 1} indicating
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX |
|
||||
* GT | LT condition is not met); {@code -2} indicating there is no such field; {@literal null} when used in
|
||||
* pipeline / transaction.
|
||||
* @return changes to the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @throws IllegalArgumentException if the instant is {@literal null} or too large to represent as a {@code Date}.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpireat/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
@@ -85,11 +78,9 @@ public interface BoundHashFieldExpirationOperations<HK> {
|
||||
ExpireChanges<HK> expireAt(Instant expireAt);
|
||||
|
||||
/**
|
||||
* Remove the expiration from given {@code hashKey} .
|
||||
* Remove the expiration from the bound hash key/hash fields.
|
||||
*
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 1} indicating expiration time is
|
||||
* removed; {@code -1} field has no expiration time to be removed; {@code -2} indicating there is no such
|
||||
* field; {@literal null} when used in pipeline / transaction.
|
||||
* @return changes to the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hpersist/">Redis Documentation: HPERSIST</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -97,12 +88,9 @@ public interface BoundHashFieldExpirationOperations<HK> {
|
||||
ExpireChanges<HK> persist();
|
||||
|
||||
/**
|
||||
* Get the time to live for {@code hashKey} in seconds.
|
||||
* Get the time to live for bound hash key/hash fields in seconds.
|
||||
*
|
||||
* @return a list of {@link Long} values for each of the fields provided: the time to live in seconds; or a negative
|
||||
* value to signal an error. The command returns {@code -1} if the key exists but has no associated expiration
|
||||
* time. The command returns {@code -2} if the key does not exist; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* @return the actual expirations in seconds for the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/httl/">Redis Documentation: HTTL</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -110,12 +98,10 @@ public interface BoundHashFieldExpirationOperations<HK> {
|
||||
Expirations<HK> getTimeToLive();
|
||||
|
||||
/**
|
||||
* Get the time to live for {@code hashKey} and convert it to the given {@link TimeUnit}.
|
||||
* Get the time to live for the bound hash key/hash fields and convert it to the given {@link TimeUnit}.
|
||||
*
|
||||
* @param timeUnit must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: the time to live in seconds; or a negative
|
||||
* value to signal an error. The command returns {@code -1} if the key exists but has no associated expiration
|
||||
* time. The command returns {@code -2} if the key does not exist; {@literal null} when used in pipeline /
|
||||
* @return the actual expirations for the hash fields in the given time unit. {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/httl/">Redis Documentation: HTTL</a>
|
||||
* @since 3.5
|
||||
|
||||
@@ -29,7 +29,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.redis.connection.Hash.FieldExpirationOptions;
|
||||
import org.springframework.data.redis.connection.ReactiveHashCommands;
|
||||
@@ -249,13 +248,14 @@ class DefaultReactiveHashOperations<H, HK, HV> implements ReactiveHashOperations
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<ExpireChanges<HK>> expire(H key, Expiration expiration, FieldExpirationOptions options, Collection<HK> hashKeys) {
|
||||
public Mono<ExpireChanges<HK>> expire(H key, Expiration expiration, FieldExpirationOptions options,
|
||||
Collection<HK> hashKeys) {
|
||||
|
||||
List<HK> orderedKeys = List.copyOf(hashKeys);
|
||||
ByteBuffer rawKey = rawKey(key);
|
||||
List<ByteBuffer> rawHashKeys = orderedKeys.stream().map(this::rawHashKey).toList();
|
||||
|
||||
Mono<List<Long>> raw =createFlux(connection -> {
|
||||
Mono<List<Long>> raw = createFlux(connection -> {
|
||||
return connection
|
||||
.applyExpiration(Mono.just(ExpireCommand.expire(rawHashKeys, expiration).from(rawKey).withOptions(options)))
|
||||
.map(NumericResponse::getOutput);
|
||||
|
||||
@@ -235,11 +235,7 @@ public interface HashOperations<H, HK, HV> {
|
||||
* @param key must not be {@literal null}.
|
||||
* @param timeout the amount of time after which the key will be expired, must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is 0; {@code 1} indicating expiration time
|
||||
* is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX | GT | LT condition
|
||||
* is not met); {@code -2} indicating there is no such field; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* @return changes to the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @throws IllegalArgumentException if the timeout is {@literal null}.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpire/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
@@ -253,11 +249,7 @@ public interface HashOperations<H, HK, HV> {
|
||||
* @param key must not be {@literal null}.
|
||||
* @param expireAt must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is in the past; {@code 1} indicating
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX |
|
||||
* GT | LT condition is not met); {@code -2} indicating there is no such field; {@literal null} when used in
|
||||
* pipeline / transaction.
|
||||
* @return changes to the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @throws IllegalArgumentException if the instant is {@literal null} or too large to represent as a {@code Date}.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpireat/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
@@ -272,11 +264,7 @@ public interface HashOperations<H, HK, HV> {
|
||||
* @param expiration must not be {@literal null}.
|
||||
* @param options must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is in the past; {@code 1} indicating
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX |
|
||||
* GT | LT condition is not met); {@code -2} indicating there is no such field; {@literal null} when used in
|
||||
* pipeline / transaction.
|
||||
* @return changes to the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @throws IllegalArgumentException if the instant is {@literal null} or too large to represent as a {@code Date}.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpireat/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
@@ -289,9 +277,7 @@ public interface HashOperations<H, HK, HV> {
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 1} indicating expiration time is
|
||||
* removed; {@code -1} field has no expiration time to be removed; {@code -2} indicating there is no such
|
||||
* field; {@literal null} when used in pipeline / transaction.
|
||||
* @return changes to the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hpersist/">Redis Documentation: HPERSIST</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -303,10 +289,7 @@ public interface HashOperations<H, HK, HV> {
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: the time to live in seconds; or a negative
|
||||
* value to signal an error. The command returns {@code -1} if the key exists but has no associated expiration
|
||||
* time. The command returns {@code -2} if the key does not exist; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* @return the actual expirations in seconds for the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/httl/">Redis Documentation: HTTL</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -321,10 +304,7 @@ public interface HashOperations<H, HK, HV> {
|
||||
* @param key must not be {@literal null}.
|
||||
* @param timeUnit must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: the time to live in seconds; or a negative
|
||||
* value to signal an error. The command returns {@code -1} if the key exists but has no associated expiration
|
||||
* time. The command returns {@code -2} if the key does not exist; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* @return the actual expirations for the hash fields. {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/httl/">Redis Documentation: HTTL</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
|
||||
@@ -238,8 +238,31 @@ public interface ReactiveHashOperations<H, HK, HV> {
|
||||
*/
|
||||
Flux<Map.Entry<HK, HV>> scan(H key, ScanOptions options);
|
||||
|
||||
/**
|
||||
* Set time to live for given {@literal hashKeys} stored within {@literal key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param timeout the amount of time after which the key will be expired, must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a {@link Mono} emitting changes to the hash fields.
|
||||
* @throws IllegalArgumentException if the timeout is {@literal null}.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpire/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
Mono<ExpireChanges<HK>> expire(H key, Duration timeout, Collection<HK> hashKeys);
|
||||
|
||||
/**
|
||||
* Set time to live for given {@literal hashKeys} stored within {@literal key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param expiration must not be {@literal null}.
|
||||
* @param options additional options to apply.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a {@link Mono} emitting changes to the hash fields.
|
||||
* @throws IllegalArgumentException if the timeout is {@literal null}.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpire/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
Mono<ExpireChanges<HK>> expire(H key, Expiration expiration, FieldExpirationOptions options, Collection<HK> hashKeys);
|
||||
|
||||
/**
|
||||
@@ -248,11 +271,7 @@ public interface ReactiveHashOperations<H, HK, HV> {
|
||||
* @param key must not be {@literal null}.
|
||||
* @param expireAt must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 2} indicating the specific field is
|
||||
* deleted already due to expiration, or provided expiry interval is in the past; {@code 1} indicating
|
||||
* expiration time is set/updated; {@code 0} indicating the expiration time is not set (a provided NX | XX |
|
||||
* GT | LT condition is not met); {@code -2} indicating there is no such field; {@literal null} when used in
|
||||
* pipeline / transaction.
|
||||
* @return a {@link Mono} emitting changes to the hash fields.
|
||||
* @throws IllegalArgumentException if the instant is {@literal null} or too large to represent as a {@code Date}.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hexpireat/">Redis Documentation: HEXPIRE</a>
|
||||
* @since 3.5
|
||||
@@ -265,9 +284,7 @@ public interface ReactiveHashOperations<H, HK, HV> {
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: {@code 1} indicating expiration time is
|
||||
* removed; {@code -1} field has no expiration time to be removed; {@code -2} indicating there is no such
|
||||
* field; {@literal null} when used in pipeline / transaction.
|
||||
* @return a {@link Mono} emitting changes to the hash fields.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/hpersist/">Redis Documentation: HPERSIST</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -279,10 +296,7 @@ public interface ReactiveHashOperations<H, HK, HV> {
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: the time to live in seconds; or a negative
|
||||
* value to signal an error. The command returns {@code -1} if the key exists but has no associated expiration
|
||||
* time. The command returns {@code -2} if the key does not exist; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* @return a {@link Mono} emitting {@link Expirations} of the hash fields.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/httl/">Redis Documentation: HTTL</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
@@ -297,10 +311,7 @@ public interface ReactiveHashOperations<H, HK, HV> {
|
||||
* @param key must not be {@literal null}.
|
||||
* @param timeUnit must not be {@literal null}.
|
||||
* @param hashKeys must not be {@literal null}.
|
||||
* @return a list of {@link Long} values for each of the fields provided: the time to live in seconds; or a negative
|
||||
* value to signal an error. The command returns {@code -1} if the key exists but has no associated expiration
|
||||
* time. The command returns {@code -2} if the key does not exist; {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* @return a {@link Mono} emitting {@link Expirations} of the hash fields.
|
||||
* @see <a href="https://redis.io/docs/latest/commands/httl/">Redis Documentation: HTTL</a>
|
||||
* @since 3.5
|
||||
*/
|
||||
|
||||
@@ -376,7 +376,6 @@ public interface RedisOperations<K, V> {
|
||||
@Nullable
|
||||
Boolean persist(K key);
|
||||
|
||||
// TODO: Add TimeToLive (getTimeToLive)
|
||||
/**
|
||||
* Get the time to live for {@code key} in seconds.
|
||||
*
|
||||
|
||||
@@ -15,24 +15,48 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assumptions.*;
|
||||
import static org.awaitility.Awaitility.*;
|
||||
import static org.junit.jupiter.api.condition.OS.*;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.*;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldIncrBy.Overflow.*;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.*;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchStoreCommandArgs.*;
|
||||
import static org.springframework.data.redis.core.ScanOptions.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.assertj.core.api.Assertions.within;
|
||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.junit.jupiter.api.condition.OS.MAC;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.create;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldIncrBy.Overflow.FAIL;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.INT_8;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.signed;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.unsigned;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_1;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_2;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_3;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_1;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_2;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_3;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_4;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit.KILOMETERS;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.newGeoSearchArgs;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchStoreCommandArgs.newGeoSearchStoreArgs;
|
||||
import static org.springframework.data.redis.core.ScanOptions.scanOptions;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -753,7 +777,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
assertThat(stringSerializer.deserialize((byte[]) getResults().get(1))).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExecuteHashFieldExpiration() {
|
||||
|
||||
@@ -3473,7 +3497,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(new Object[] { 0L }));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireReturnsSuccessAndSetsTTL() {
|
||||
|
||||
@@ -3484,10 +3508,10 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
List<Object> results = getResults();
|
||||
assertThat(results.get(0)).isEqualTo(Boolean.TRUE);
|
||||
assertThat((List) results.get(1)).contains(1L);
|
||||
assertThat((List) results.get(2)).allSatisfy( value -> assertThat((Long)value).isBetween(0L, 5L));
|
||||
assertThat((List) results.get(2)).allSatisfy(value -> assertThat((Long) value).isBetween(0L, 5L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
@@ -3498,7 +3522,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(-2L), List.of(-2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireReturnsTwoWhenZeroProvided() {
|
||||
|
||||
@@ -3508,7 +3532,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HPEXPIRE")
|
||||
public void hpExpireReturnsSuccessAndSetsTTL() {
|
||||
|
||||
@@ -3519,10 +3543,10 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
List<Object> results = getResults();
|
||||
assertThat(results.get(0)).isEqualTo(Boolean.TRUE);
|
||||
assertThat((List) results.get(1)).contains(1L);
|
||||
assertThat((List) results.get(2)).allSatisfy( value -> assertThat((Long)value).isBetween(0L, 5000L));
|
||||
assertThat((List) results.get(2)).allSatisfy(value -> assertThat((Long) value).isBetween(0L, 5000L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HPEXPIRE")
|
||||
public void hpExpireReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
@@ -3533,7 +3557,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(-2L), List.of(-2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HPEXPIRE")
|
||||
public void hpExpireReturnsTwoWhenZeroProvided() {
|
||||
|
||||
@@ -3543,7 +3567,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIREAT")
|
||||
public void hExpireAtReturnsSuccessAndSetsTTL() {
|
||||
|
||||
@@ -3556,10 +3580,10 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
List<Object> results = getResults();
|
||||
assertThat(results.get(0)).isEqualTo(Boolean.TRUE);
|
||||
assertThat((List) results.get(1)).contains(1L);
|
||||
assertThat((List) results.get(2)).allSatisfy( value -> assertThat((Long)value).isBetween(0L, 5L));
|
||||
assertThat((List) results.get(2)).allSatisfy(value -> assertThat((Long) value).isBetween(0L, 5L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIREAT")
|
||||
public void hExpireAtReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
@@ -3572,7 +3596,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(-2L), List.of(-2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIREAT")
|
||||
public void hExpireAtReturnsTwoWhenZeroProvided() {
|
||||
|
||||
@@ -3584,7 +3608,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIREAT")
|
||||
public void hpExpireAtReturnsSuccessAndSetsTTL() {
|
||||
|
||||
@@ -3597,10 +3621,10 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
List<Object> results = getResults();
|
||||
assertThat(results.get(0)).isEqualTo(Boolean.TRUE);
|
||||
assertThat((List) results.get(1)).contains(1L);
|
||||
assertThat((List) results.get(2)).allSatisfy( value -> assertThat((Long)value).isBetween(0L, 5L));
|
||||
assertThat((List) results.get(2)).allSatisfy(value -> assertThat((Long) value).isBetween(0L, 5L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIREAT")
|
||||
public void hpExpireAtReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
@@ -3613,7 +3637,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(-2L), List.of(-2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HPEXPIREAT")
|
||||
public void hpExpireAdReturnsTwoWhenZeroProvided() {
|
||||
|
||||
@@ -3625,7 +3649,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HPERSIST")
|
||||
public void hPersistReturnsSuccessAndPersistsField() {
|
||||
|
||||
@@ -3637,7 +3661,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(1L), List.of(1L), List.of(-1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HPERSIST")
|
||||
public void hPersistReturnsMinusOneWhenFieldDoesNotHaveExpiration() {
|
||||
|
||||
@@ -3647,7 +3671,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(-1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HPERSIST")
|
||||
public void hPersistReturnsMinusTwoWhenFieldOrKeyMissing() {
|
||||
|
||||
@@ -3658,7 +3682,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(-2L), List.of(-2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HTTL")
|
||||
public void hTtlReturnsMinusOneWhenFieldHasNoExpiration() {
|
||||
|
||||
@@ -3668,7 +3692,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(-1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HTTL")
|
||||
public void hTtlReturnsMinusIndependendOfTimeUnitOneWhenFieldHasNoExpiration() {
|
||||
|
||||
@@ -3678,7 +3702,7 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
verifyResults(Arrays.asList(Boolean.TRUE, List.of(-1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HTTL")
|
||||
public void hTtlReturnsMinusTwoWhenFieldOrKeyMissing() {
|
||||
|
||||
|
||||
@@ -15,17 +15,37 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.jedis;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.*;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldIncrBy.Overflow.*;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.*;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*;
|
||||
import static org.springframework.data.redis.connection.RedisListCommands.*;
|
||||
import static org.springframework.data.redis.connection.RedisZSetCommands.*;
|
||||
import static org.springframework.data.redis.core.ScanOptions.*;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.create;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldIncrBy.Overflow.FAIL;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.INT_8;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.signed;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.unsigned;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.CLUSTER_HOST;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_1;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_2;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_3;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.MASTER_NODE_1_PORT;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.MASTER_NODE_2_PORT;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.MASTER_NODE_3_PORT;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.REPLICAOF_NODE_1_PORT;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.SAME_SLOT_KEY_1;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.SAME_SLOT_KEY_2;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.SAME_SLOT_KEY_3;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_1;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_2;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_3;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit.KILOMETERS;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs;
|
||||
import static org.springframework.data.redis.connection.RedisListCommands.Direction;
|
||||
import static org.springframework.data.redis.connection.RedisListCommands.Position;
|
||||
import static org.springframework.data.redis.connection.RedisZSetCommands.Range;
|
||||
import static org.springframework.data.redis.core.ScanOptions.NONE;
|
||||
import static org.springframework.data.redis.core.ScanOptions.scanOptions;
|
||||
|
||||
import redis.clients.jedis.ConnectionPool;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
@@ -37,14 +57,23 @@ import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.domain.Range.Bound;
|
||||
@@ -1040,9 +1069,10 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hStrLen(KEY_1_BYTES, KEY_1_BYTES)).isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireReturnsSuccessAndSetsTTL() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hExpire(KEY_1_BYTES, 5L, KEY_2_BYTES)).contains(1L);
|
||||
@@ -1050,9 +1080,10 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
.allSatisfy(val -> assertThat(val).isBetween(0L, 5L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
// missing field
|
||||
assertThat(clusterConnection.hashCommands().hExpire(KEY_1_BYTES, 5L, KEY_1_BYTES)).contains(-2L);
|
||||
@@ -1060,27 +1091,30 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hExpire(KEY_2_BYTES, 5L, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireReturnsTwoWhenZeroProvided() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hExpire(KEY_1_BYTES, 0L, KEY_2_BYTES)).contains(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireReturnsSuccessAndSetsTTL() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hpExpire(KEY_1_BYTES, 5000L, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, TimeUnit.MILLISECONDS,KEY_2_BYTES))
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, TimeUnit.MILLISECONDS, KEY_2_BYTES))
|
||||
.allSatisfy(val -> assertThat(val).isBetween(0L, 5000L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
// missing field
|
||||
assertThat(clusterConnection.hashCommands().hpExpire(KEY_1_BYTES, 5L, KEY_1_BYTES)).contains(-2L);
|
||||
@@ -1088,26 +1122,31 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hpExpire(KEY_2_BYTES, 5L, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireReturnsTwoWhenZeroProvided() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hpExpire(KEY_1_BYTES, 0L, KEY_2_BYTES)).contains(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireAtReturnsSuccessAndSetsTTL() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
long inFiveSeconds = Instant.now().plusSeconds(5L).getEpochSecond();
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hExpireAt(KEY_1_BYTES, inFiveSeconds, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, KEY_2_BYTES)).allSatisfy(val -> assertThat(val).isBetween(0L, 5L));
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, KEY_2_BYTES))
|
||||
.allSatisfy(val -> assertThat(val).isBetween(0L, 5L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireAtReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
long inFiveSeconds = Instant.now().plusSeconds(5L).getEpochSecond();
|
||||
|
||||
@@ -1117,27 +1156,31 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hExpireAt(KEY_2_BYTES, inFiveSeconds, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireAdReturnsTwoWhenZeroProvided() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hExpireAt(KEY_1_BYTES, 0L, KEY_2_BYTES)).contains(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireAtReturnsSuccessAndSetsTTL() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
long inFiveSeconds = Instant.now().plusSeconds(5L).toEpochMilli();
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hpExpireAt(KEY_1_BYTES, inFiveSeconds, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, TimeUnit.MILLISECONDS, KEY_2_BYTES))
|
||||
.allSatisfy(val -> assertThat(val).isBetween(0L, 5000L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireAtReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
long inFiveSeconds = Instant.now().plusSeconds(5L).toEpochMilli();
|
||||
|
||||
@@ -1147,55 +1190,60 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hpExpireAt(KEY_2_BYTES, inFiveSeconds, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireAdReturnsTwoWhenZeroProvided() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hpExpireAt(KEY_1_BYTES, 0L, KEY_2_BYTES)).contains(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hPersistReturnsSuccessAndPersistsField() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hExpire(KEY_1_BYTES, 5L, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_1_BYTES, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_1_BYTES, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, KEY_2_BYTES)).contains(-1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hPersistReturnsMinusOneWhenFieldDoesNotHaveExpiration() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_1_BYTES, KEY_2_BYTES)).contains(-1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hPersistReturnsMinusTwoWhenFieldOrKeyMissing() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_1_BYTES, KEY_1_BYTES)).contains(-2L);
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_3_BYTES,KEY_2_BYTES)).contains(-2L);
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_3_BYTES, KEY_2_BYTES)).contains(-2L);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hTtlReturnsMinusOneWhenFieldHasNoExpiration() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, KEY_2_BYTES)).contains(-1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hTtlReturnsMinusTwoWhenFieldOrKeyMissing() {
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, KEY_1_BYTES)).contains(-2L);
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_3_BYTES,KEY_2_BYTES)).contains(-2L);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_3_BYTES, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-315
|
||||
@@ -1346,7 +1394,7 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
.isEqualTo(VALUE_2_BYTES);
|
||||
assertThat(
|
||||
clusterConnection.bLMove(SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES, Direction.RIGHT, Direction.LEFT, 0.01))
|
||||
.isNull();
|
||||
.isNull();
|
||||
|
||||
assertThat(nativeConnection.lrange(SAME_SLOT_KEY_1, 0, -1)).isEmpty();
|
||||
assertThat(nativeConnection.lrange(SAME_SLOT_KEY_2, 0, -1)).containsExactly(VALUE_2, VALUE_3);
|
||||
@@ -2946,13 +2994,13 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
|
||||
assertThat(clusterConnection.stringCommands().bitField(JedisConverters.toBytes(KEY_1),
|
||||
create().incr(unsigned(2)).valueAt(BitFieldSubCommands.Offset.offset(102L)).overflow(FAIL).by(1L)))
|
||||
.containsExactly(1L);
|
||||
.containsExactly(1L);
|
||||
assertThat(clusterConnection.stringCommands().bitField(JedisConverters.toBytes(KEY_1),
|
||||
create().incr(unsigned(2)).valueAt(BitFieldSubCommands.Offset.offset(102L)).overflow(FAIL).by(1L)))
|
||||
.containsExactly(2L);
|
||||
.containsExactly(2L);
|
||||
assertThat(clusterConnection.stringCommands().bitField(JedisConverters.toBytes(KEY_1),
|
||||
create().incr(unsigned(2)).valueAt(BitFieldSubCommands.Offset.offset(102L)).overflow(FAIL).by(1L)))
|
||||
.containsExactly(3L);
|
||||
.containsExactly(3L);
|
||||
assertThat(clusterConnection.stringCommands()
|
||||
.bitField(JedisConverters.toBytes(KEY_1),
|
||||
create().incr(unsigned(2)).valueAt(BitFieldSubCommands.Offset.offset(102L)).overflow(FAIL).by(1L))
|
||||
@@ -2964,7 +3012,7 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
|
||||
assertThat(clusterConnection.stringCommands().bitField(JedisConverters.toBytes(KEY_1),
|
||||
create().incr(signed(5)).valueAt(BitFieldSubCommands.Offset.offset(100L)).by(1L).get(unsigned(4)).valueAt(0L)))
|
||||
.containsExactly(1L, 0L);
|
||||
.containsExactly(1L, 0L);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-562
|
||||
@@ -2974,13 +3022,13 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
clusterConnection.stringCommands().bitField(JedisConverters.toBytes(KEY_1),
|
||||
create().set(INT_8).valueAt(BitFieldSubCommands.Offset.offset(0L).multipliedByTypeLength()).to(100L)
|
||||
.set(INT_8).valueAt(BitFieldSubCommands.Offset.offset(1L).multipliedByTypeLength()).to(200L)))
|
||||
.containsExactly(0L, 0L);
|
||||
.containsExactly(0L, 0L);
|
||||
assertThat(
|
||||
clusterConnection.stringCommands()
|
||||
.bitField(JedisConverters.toBytes(KEY_1),
|
||||
create().get(INT_8).valueAt(BitFieldSubCommands.Offset.offset(0L).multipliedByTypeLength()).get(INT_8)
|
||||
.valueAt(BitFieldSubCommands.Offset.offset(1L).multipliedByTypeLength()))).containsExactly(100L,
|
||||
-56L);
|
||||
.valueAt(BitFieldSubCommands.Offset.offset(1L).multipliedByTypeLength())))
|
||||
.containsExactly(100L, -56L);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-1005
|
||||
@@ -3125,7 +3173,8 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(topology).isInstanceOf(JedisClusterConnection.JedisClusterTopology.class);
|
||||
|
||||
assertThat(provider.shouldUseCachedValue(null)).isFalse();
|
||||
assertThat(provider.shouldUseCachedValue(new JedisClusterConnection.JedisClusterTopology(Set.of(), System.currentTimeMillis() - 101, 100))).isFalse();
|
||||
assertThat(provider.shouldUseCachedValue(
|
||||
new JedisClusterConnection.JedisClusterTopology(Set.of(), System.currentTimeMillis() - 101, 100))).isFalse();
|
||||
assertThat(provider.shouldUseCachedValue(
|
||||
new JedisClusterConnection.JedisClusterTopology(Set.of(), System.currentTimeMillis() + 100, 100))).isTrue();
|
||||
}
|
||||
|
||||
@@ -15,16 +15,35 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.*;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldIncrBy.Overflow.*;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.*;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*;
|
||||
import static org.springframework.data.redis.connection.RedisZSetCommands.*;
|
||||
import static org.springframework.data.redis.core.ScanOptions.*;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.create;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldIncrBy.Overflow.FAIL;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.INT_8;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.signed;
|
||||
import static org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldType.unsigned;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.CLUSTER_HOST;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_1;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_2;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_3;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.KEY_4;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.MASTER_NODE_1_PORT;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.MASTER_NODE_2_PORT;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.MASTER_NODE_3_PORT;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.REPLICAOF_NODE_1_PORT;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.SAME_SLOT_KEY_1;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.SAME_SLOT_KEY_2;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.SAME_SLOT_KEY_3;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_1;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_2;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_3;
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.VALUE_4;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit.KILOMETERS;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs;
|
||||
import static org.springframework.data.redis.connection.RedisZSetCommands.Range;
|
||||
import static org.springframework.data.redis.core.ScanOptions.scanOptions;
|
||||
|
||||
import io.lettuce.core.cluster.RedisClusterClient;
|
||||
import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;
|
||||
@@ -33,7 +52,17 @@ import io.lettuce.core.codec.ByteArrayCodec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.data.Offset;
|
||||
@@ -49,11 +78,21 @@ import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.*;
|
||||
import org.springframework.data.redis.connection.BitFieldSubCommands;
|
||||
import org.springframework.data.redis.connection.ClusterConnectionTests;
|
||||
import org.springframework.data.redis.connection.ClusterSlotHashUtil;
|
||||
import org.springframework.data.redis.connection.ClusterTestVariables;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.DefaultSortParameters;
|
||||
import org.springframework.data.redis.connection.Limit;
|
||||
import org.springframework.data.redis.connection.RedisClusterConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisClusterConnection;
|
||||
import org.springframework.data.redis.connection.RedisClusterNode;
|
||||
import org.springframework.data.redis.connection.RedisClusterNode.SlotRange;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
|
||||
import org.springframework.data.redis.connection.RedisListCommands;
|
||||
import org.springframework.data.redis.connection.RedisListCommands.Position;
|
||||
import org.springframework.data.redis.connection.RedisNode;
|
||||
import org.springframework.data.redis.connection.RedisServerCommands.FlushOption;
|
||||
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
|
||||
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
|
||||
@@ -1097,7 +1136,7 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hStrLen(KEY_1_BYTES, KEY_1_BYTES)).isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireReturnsSuccessAndSetsTTL() {
|
||||
|
||||
@@ -1107,7 +1146,7 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hTtl(KEY_1_BYTES, KEY_2_BYTES)).allSatisfy(val -> assertThat(val).isBetween(0L, 5L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
@@ -1118,17 +1157,19 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hExpire(KEY_2_BYTES, 5L, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireReturnsTwoWhenZeroProvided() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hExpire(KEY_1_BYTES, 0L, KEY_2_BYTES)).contains(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireReturnsSuccessAndSetsTTL() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hpExpire(KEY_1_BYTES, 5000L, KEY_2_BYTES)).contains(1L);
|
||||
@@ -1136,7 +1177,7 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
.allSatisfy(val -> assertThat(val).isBetween(0L, 5000L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
@@ -1147,7 +1188,7 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hpExpire(KEY_2_BYTES, 5L, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireReturnsTwoWhenZeroProvided() {
|
||||
|
||||
@@ -1156,17 +1197,18 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hpExpire(KEY_1_BYTES, 0L, KEY_2_BYTES)).contains(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireAtReturnsSuccessAndSetsTTL() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
long inFiveSeconds = Instant.now().plusSeconds(5L).getEpochSecond();
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hExpireAt(KEY_1_BYTES, inFiveSeconds, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hTtl(KEY_1_BYTES, KEY_2_BYTES)).allSatisfy(val -> assertThat(val).isBetween(0L, 5L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireAtReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
@@ -1180,9 +1222,10 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hExpireAt(KEY_2_BYTES, inFiveSeconds, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hExpireAdReturnsTwoWhenZeroProvided() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hExpireAt(KEY_1_BYTES, 0L, KEY_2_BYTES)).contains(2L);
|
||||
@@ -1194,12 +1237,13 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
long inFiveSeconds = Instant.now().plusSeconds(5L).toEpochMilli();
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hpExpireAt(KEY_1_BYTES, inFiveSeconds, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hpTtl(KEY_1_BYTES, KEY_2_BYTES))
|
||||
.allSatisfy(val -> assertThat(val).isGreaterThan(1000L).isLessThanOrEqualTo(5000L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireAtReturnsMinusTwoWhenFieldDoesNotExist() {
|
||||
|
||||
@@ -1212,7 +1256,7 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hpExpireAt(KEY_2_BYTES, inFiveSeconds, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hpExpireAdReturnsTwoWhenZeroProvided() {
|
||||
|
||||
@@ -1221,17 +1265,17 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hpExpireAt(KEY_1_BYTES, 0L, KEY_2_BYTES)).contains(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hPersistReturnsSuccessAndPersistsField() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
assertThat(clusterConnection.hashCommands().hExpire(KEY_1_BYTES, 5L, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_1_BYTES, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_1_BYTES, KEY_2_BYTES)).contains(1L);
|
||||
assertThat(clusterConnection.hTtl(KEY_1_BYTES, KEY_2_BYTES)).contains(-1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hPersistReturnsMinusOneWhenFieldDoesNotHaveExpiration() {
|
||||
|
||||
@@ -1239,17 +1283,18 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_1_BYTES, KEY_2_BYTES)).contains(-1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hPersistReturnsMinusTwoWhenFieldOrKeyMissing() {
|
||||
|
||||
nativeConnection.hset(KEY_1, KEY_2, VALUE_3);
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_1_BYTES, KEY_1_BYTES)).contains(-2L);
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_3_BYTES,KEY_2_BYTES)).contains(-2L);
|
||||
assertThat(clusterConnection.hashCommands().hPersist(KEY_3_BYTES, KEY_2_BYTES)).contains(-2L);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hTtlReturnsMinusOneWhenFieldHasNoExpiration() {
|
||||
|
||||
@@ -1259,12 +1304,12 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, TimeUnit.HOURS, KEY_2_BYTES)).contains(-1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
public void hTtlReturnsMinusTwoWhenFieldOrKeyMissing() {
|
||||
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_1_BYTES, KEY_1_BYTES)).contains(-2L);
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_3_BYTES,KEY_2_BYTES)).contains(-2L);
|
||||
assertThat(clusterConnection.hashCommands().hTtl(KEY_3_BYTES, KEY_2_BYTES)).contains(-2L);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-315
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.springframework.data.redis.test.condition.EnabledOnCommand;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -31,6 +30,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnCommand;
|
||||
import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest;
|
||||
|
||||
/**
|
||||
@@ -107,8 +107,7 @@ public class LettuceReactiveHashCommandsIntegrationTests extends LettuceReactive
|
||||
nativeCommands.hset(KEY_1, FIELD_3, VALUE_3);
|
||||
|
||||
connection.hashCommands().hMGet(KEY_1_BBUFFER, Arrays.asList(FIELD_1_BBUFFER, FIELD_3_BBUFFER))
|
||||
.as(StepVerifier::create)
|
||||
.consumeNextWith(actual -> {
|
||||
.as(StepVerifier::create).consumeNextWith(actual -> {
|
||||
|
||||
assertThat(actual).contains(VALUE_1_BBUFFER, VALUE_3_BBUFFER);
|
||||
|
||||
@@ -124,13 +123,11 @@ public class LettuceReactiveHashCommandsIntegrationTests extends LettuceReactive
|
||||
connection.hashCommands().hMGet(KEY_1_BBUFFER, Collections.singletonList(FIELD_1_BBUFFER)).as(StepVerifier::create)
|
||||
.expectNext(Collections.singletonList(VALUE_1_BBUFFER)).verifyComplete();
|
||||
|
||||
connection.hashCommands().hMGet(KEY_1_BBUFFER, Collections.singletonList(FIELD_2_BBUFFER))
|
||||
.as(StepVerifier::create)
|
||||
connection.hashCommands().hMGet(KEY_1_BBUFFER, Collections.singletonList(FIELD_2_BBUFFER)).as(StepVerifier::create)
|
||||
.expectNext(Collections.singletonList(null)).verifyComplete();
|
||||
|
||||
connection.hashCommands().hMGet(KEY_1_BBUFFER, Arrays.asList(FIELD_1_BBUFFER, FIELD_2_BBUFFER, FIELD_3_BBUFFER))
|
||||
.as(StepVerifier::create)
|
||||
.expectNext(Arrays.asList(VALUE_1_BBUFFER, null, VALUE_3_BBUFFER)).verifyComplete();
|
||||
.as(StepVerifier::create).expectNext(Arrays.asList(VALUE_1_BBUFFER, null, VALUE_3_BBUFFER)).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // DATAREDIS-525
|
||||
@@ -197,8 +194,7 @@ public class LettuceReactiveHashCommandsIntegrationTests extends LettuceReactive
|
||||
nativeCommands.hset(KEY_1, FIELD_3, VALUE_3);
|
||||
|
||||
connection.hashCommands().hDel(KEY_1_BBUFFER, Arrays.asList(FIELD_1_BBUFFER, FIELD_3_BBUFFER))
|
||||
.as(StepVerifier::create)
|
||||
.expectNext(2L).verifyComplete();
|
||||
.as(StepVerifier::create).expectNext(2L).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // DATAREDIS-525
|
||||
@@ -293,62 +289,50 @@ public class LettuceReactiveHashCommandsIntegrationTests extends LettuceReactive
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void hExpireShouldHandleMultipleParametersCorrectly() {
|
||||
|
||||
assertThat(nativeCommands.hset(KEY_1, FIELD_1, VALUE_1)).isTrue();
|
||||
assertThat(nativeCommands.hset(KEY_1, FIELD_2, VALUE_2)).isTrue();
|
||||
final var fields = Arrays.asList(FIELD_1_BBUFFER, FIELD_2_BBUFFER, FIELD_3_BBUFFER);
|
||||
|
||||
connection.hashCommands().hExpire(KEY_1_BBUFFER, Duration.ofSeconds(1), fields).as(StepVerifier::create) //
|
||||
.expectNext(1L)
|
||||
.expectNext(1L)
|
||||
.expectNext(-2L)
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.expectNext(1L).expectNext(1L).expectNext(-2L).expectComplete().verify();
|
||||
|
||||
assertThat(nativeCommands.httl(KEY_1, FIELD_1)).allSatisfy(it -> assertThat(it).isBetween(0L, 1000L));
|
||||
assertThat(nativeCommands.httl(KEY_1, FIELD_2)).allSatisfy(it -> assertThat(it).isBetween(0L, 1000L));
|
||||
assertThat(nativeCommands.httl(KEY_1, FIELD_3)).allSatisfy(it -> assertThat(it).isEqualTo(-2L));
|
||||
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void hExpireAtShouldHandleMultipleParametersCorrectly() {
|
||||
|
||||
assertThat(nativeCommands.hset(KEY_1, FIELD_1, VALUE_1)).isTrue();
|
||||
assertThat(nativeCommands.hset(KEY_1, FIELD_2, VALUE_2)).isTrue();
|
||||
final var fields = Arrays.asList(FIELD_1_BBUFFER, FIELD_2_BBUFFER, FIELD_3_BBUFFER);
|
||||
|
||||
connection.hashCommands().hExpireAt(KEY_1_BBUFFER, Instant.now().plusSeconds(1), fields).as(StepVerifier::create) //
|
||||
.expectNext(1L)
|
||||
.expectNext(1L)
|
||||
.expectNext(-2L)
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.expectNext(1L).expectNext(1L).expectNext(-2L).expectComplete().verify();
|
||||
|
||||
assertThat(nativeCommands.httl(KEY_1, FIELD_1, FIELD_2)).allSatisfy(it -> assertThat(it).isBetween(0L, 1000L));
|
||||
assertThat(nativeCommands.httl(KEY_1, FIELD_3)).allSatisfy(it -> assertThat(it).isEqualTo(-2L));
|
||||
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void hPersistShouldPersistFields() {
|
||||
|
||||
assertThat(nativeCommands.hset(KEY_1, FIELD_1, VALUE_1)).isTrue();
|
||||
assertThat(nativeCommands.hset(KEY_1, FIELD_2, VALUE_2)).isTrue();
|
||||
|
||||
assertThat(nativeCommands.hexpire(KEY_1, 1000, FIELD_1))
|
||||
.allSatisfy(it -> assertThat(it).isEqualTo(1L));
|
||||
assertThat(nativeCommands.hexpire(KEY_1, 1000, FIELD_1)).allSatisfy(it -> assertThat(it).isEqualTo(1L));
|
||||
|
||||
final var fields = Arrays.asList(FIELD_1_BBUFFER, FIELD_2_BBUFFER, FIELD_3_BBUFFER);
|
||||
|
||||
connection.hashCommands().hPersist(KEY_1_BBUFFER, fields).as(StepVerifier::create) //
|
||||
.expectNext(1L)
|
||||
.expectNext(-1L)
|
||||
.expectNext(-2L)
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.expectNext(1L).expectNext(-1L).expectNext(-2L).expectComplete().verify();
|
||||
|
||||
assertThat(nativeCommands.httl(KEY_1, FIELD_1, FIELD_2)).allSatisfy(it -> assertThat(it).isEqualTo(-1L));
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assumptions.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
@@ -29,7 +30,6 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.RawObjectFactory;
|
||||
import org.springframework.data.redis.StringObjectFactory;
|
||||
@@ -212,7 +212,7 @@ public class DefaultHashOperationsIntegrationTests<K, HK, HV> {
|
||||
assertThat(values).hasSize(2).containsEntry(key1, val1).containsEntry(key2, val2);
|
||||
}
|
||||
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
@EnabledOnCommand("HEXPIRE") // GH-3054
|
||||
@ParameterizedRedisTest
|
||||
void testExpireAndGetExpireMillis() {
|
||||
|
||||
@@ -237,7 +237,7 @@ public class DefaultHashOperationsIntegrationTests<K, HK, HV> {
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExpireAndGetExpireSeconds() {
|
||||
|
||||
@@ -268,7 +268,7 @@ public class DefaultHashOperationsIntegrationTests<K, HK, HV> {
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testBoundExpireAndGetExpireSeconds() {
|
||||
|
||||
@@ -300,7 +300,7 @@ public class DefaultHashOperationsIntegrationTests<K, HK, HV> {
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExpireAtAndGetExpireMillis() {
|
||||
|
||||
@@ -325,7 +325,7 @@ public class DefaultHashOperationsIntegrationTests<K, HK, HV> {
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void expireThrowsErrorOfNanoPrecision() {
|
||||
|
||||
@@ -336,7 +336,7 @@ public class DefaultHashOperationsIntegrationTests<K, HK, HV> {
|
||||
.isThrownBy(() -> redisTemplate.opsForHash().getTimeToLive(key, TimeUnit.NANOSECONDS, List.of(key1)));
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExpireWithOptionsNone() {
|
||||
|
||||
@@ -349,12 +349,13 @@ public class DefaultHashOperationsIntegrationTests<K, HK, HV> {
|
||||
hashOps.put(key, key1, val1);
|
||||
hashOps.put(key, key2, val2);
|
||||
|
||||
ExpireChanges<Object> expire = redisTemplate.opsForHash().expire(key, org.springframework.data.redis.core.types.Expiration.seconds(20), FieldExpirationOptions.none(), List.of(key1));
|
||||
ExpireChanges<Object> expire = redisTemplate.opsForHash().expire(key,
|
||||
org.springframework.data.redis.core.types.Expiration.seconds(20), FieldExpirationOptions.none(), List.of(key1));
|
||||
|
||||
assertThat(expire.allOk()).isTrue();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExpireWithOptions() {
|
||||
|
||||
@@ -367,16 +368,20 @@ public class DefaultHashOperationsIntegrationTests<K, HK, HV> {
|
||||
hashOps.put(key, key1, val1);
|
||||
hashOps.put(key, key2, val2);
|
||||
|
||||
redisTemplate.opsForHash().expire(key, org.springframework.data.redis.core.types.Expiration.seconds(20), FieldExpirationOptions.none(), List.of(key1));
|
||||
redisTemplate.opsForHash().expire(key, org.springframework.data.redis.core.types.Expiration.seconds(60), FieldExpirationOptions.none(), List.of(key2));
|
||||
redisTemplate.opsForHash().expire(key, org.springframework.data.redis.core.types.Expiration.seconds(20),
|
||||
FieldExpirationOptions.none(), List.of(key1));
|
||||
redisTemplate.opsForHash().expire(key, org.springframework.data.redis.core.types.Expiration.seconds(60),
|
||||
FieldExpirationOptions.none(), List.of(key2));
|
||||
|
||||
ExpireChanges<Object> changes = redisTemplate.opsForHash().expire(key, org.springframework.data.redis.core.types.Expiration.seconds(30), FieldExpirationOptions.builder().gt().build(), List.of(key1, key2));
|
||||
ExpireChanges<Object> changes = redisTemplate.opsForHash().expire(key,
|
||||
org.springframework.data.redis.core.types.Expiration.seconds(30), FieldExpirationOptions.builder().gt().build(),
|
||||
List.of(key1, key2));
|
||||
|
||||
assertThat(changes.ok()).containsExactly(key1);
|
||||
assertThat(changes.skipped()).containsExactly(key2);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testPersistAndGetExpireMillis() {
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assumptions.*;
|
||||
import static org.junit.jupiter.api.condition.OS.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||
import static org.junit.jupiter.api.condition.OS.MAC;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.condition.DisabledOnOs;
|
||||
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.RawObjectFactory;
|
||||
import org.springframework.data.redis.SettingsUtils;
|
||||
@@ -506,7 +505,7 @@ public class DefaultReactiveHashOperationsIntegrationTests<K, HK, HV> {
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
@EnabledOnCommand("HEXPIRE") // GH-3054
|
||||
@ParameterizedRedisTest
|
||||
void testExpireAndGetExpireMillis() {
|
||||
|
||||
@@ -531,7 +530,7 @@ public class DefaultReactiveHashOperationsIntegrationTests<K, HK, HV> {
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExpireWithOptions() {
|
||||
|
||||
@@ -543,23 +542,32 @@ public class DefaultReactiveHashOperationsIntegrationTests<K, HK, HV> {
|
||||
|
||||
putAll(key, key1, val1, key2, val2);
|
||||
|
||||
hashOperations.expire(key, org.springframework.data.redis.core.types.Expiration.seconds(20), FieldExpirationOptions.none(), List.of(key1)).as(StepVerifier::create)//
|
||||
.assertNext(changes -> {
|
||||
assertThat(changes.allOk()).isTrue();
|
||||
}).verifyComplete();
|
||||
hashOperations.expire(key, org.springframework.data.redis.core.types.Expiration.seconds(60), FieldExpirationOptions.none(), List.of(key2)).as(StepVerifier::create)//
|
||||
.assertNext(changes -> {
|
||||
assertThat(changes.allOk()).isTrue();
|
||||
}).verifyComplete();
|
||||
hashOperations
|
||||
.expire(key, org.springframework.data.redis.core.types.Expiration.seconds(20), FieldExpirationOptions.none(),
|
||||
List.of(key1))
|
||||
.as(StepVerifier::create)//
|
||||
.assertNext(changes -> {
|
||||
assertThat(changes.allOk()).isTrue();
|
||||
}).verifyComplete();
|
||||
hashOperations
|
||||
.expire(key, org.springframework.data.redis.core.types.Expiration.seconds(60), FieldExpirationOptions.none(),
|
||||
List.of(key2))
|
||||
.as(StepVerifier::create)//
|
||||
.assertNext(changes -> {
|
||||
assertThat(changes.allOk()).isTrue();
|
||||
}).verifyComplete();
|
||||
|
||||
hashOperations.expire(key, org.springframework.data.redis.core.types.Expiration.seconds(30), FieldExpirationOptions.builder().gt().build(), List.of(key1, key2)).as(StepVerifier::create)//
|
||||
.assertNext(changes -> {
|
||||
assertThat(changes.ok()).containsExactly(key1);
|
||||
assertThat(changes.skipped()).containsExactly(key2);
|
||||
}).verifyComplete();
|
||||
hashOperations
|
||||
.expire(key, org.springframework.data.redis.core.types.Expiration.seconds(30),
|
||||
FieldExpirationOptions.builder().gt().build(), List.of(key1, key2))
|
||||
.as(StepVerifier::create)//
|
||||
.assertNext(changes -> {
|
||||
assertThat(changes.ok()).containsExactly(key1);
|
||||
assertThat(changes.skipped()).containsExactly(key2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExpireAndGetExpireSeconds() {
|
||||
|
||||
@@ -583,10 +591,9 @@ public class DefaultReactiveHashOperationsIntegrationTests<K, HK, HV> {
|
||||
assertThat(it.expirationOf(key1).raw()).isBetween(0L, 5L);
|
||||
assertThat(it.expirationOf(key2).raw()).isBetween(0L, 5L);
|
||||
}).verifyComplete();
|
||||
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExpireAtAndGetExpireMillis() {
|
||||
|
||||
@@ -611,7 +618,7 @@ public class DefaultReactiveHashOperationsIntegrationTests<K, HK, HV> {
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testPersistAndGetExpireMillis() {
|
||||
|
||||
@@ -638,7 +645,6 @@ public class DefaultReactiveHashOperationsIntegrationTests<K, HK, HV> {
|
||||
.assertNext(expirations -> {
|
||||
assertThat(expirations.persistent()).contains(key1, key2);
|
||||
}).verifyComplete();
|
||||
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // DATAREDIS-602
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.redis.support.collections;
|
||||
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.*;
|
||||
import static org.assertj.core.api.Assumptions.*;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
@@ -35,7 +36,6 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.redis.DoubleAsStringObjectFactory;
|
||||
import org.springframework.data.redis.LongAsStringObjectFactory;
|
||||
@@ -197,7 +197,7 @@ public abstract class AbstractRedisMapIntegrationTests<K, V> {
|
||||
assertThat(map.increment(k1, 10)).isEqualTo(Long.valueOf(Long.valueOf((String) v1) + 10));
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExpire() {
|
||||
|
||||
@@ -216,7 +216,7 @@ public abstract class AbstractRedisMapIntegrationTests<K, V> {
|
||||
assertThat(ops.persist()).satisfies(ExpireChanges::allOk);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest
|
||||
@ParameterizedRedisTest // GH-3054
|
||||
@EnabledOnCommand("HEXPIRE")
|
||||
void testExpireAt() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user