DATAREDIS-602 - Provide Reactive Redis Template.
Add ReactiveRedisTemplate, add tests abd add SerializerFunction and DeserializerFunction for functional Redis argument serialization. Introduce ReactiveRedisConnectionFactory and remove reactive RedisConnectionFactory methods to break the dependency to reactive types. We now no longer require Project Reactor for blocking Redis use. ReactiveRedisTemplate accepts ReactiveRedisConnectionFactory to operate on a reactive connection. The only implementation of ReactiveRedisConnectionFactory is LettuceConnectionFactory which requires by default Project Reactor. Original Pull Request: #239
This commit is contained in:
committed by
Christoph Strobl
parent
bf1a7ac8a3
commit
81657c530b
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ObjectFactory} that returns random {@link ByteBuffer}s.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class ByteBufferObjectFactory implements ObjectFactory<ByteBuffer> {
|
||||
|
||||
public ByteBuffer instance() {
|
||||
return ByteBuffer.wrap(UUID.randomUUID().toString().getBytes());
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -24,23 +24,29 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
/**
|
||||
* Basic utility to help with the destruction of {@link RedisConnectionFactory} inside JUnit 4 tests. Simply add the
|
||||
* factory during setup and then call {@link #cleanUp()} through the <tt>@AfterClass</tt> method.
|
||||
*
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public abstract class ConnectionFactoryTracker {
|
||||
|
||||
private static Set<RedisConnectionFactory> connFactories = new LinkedHashSet<RedisConnectionFactory>();
|
||||
private static Set<Object> connFactories = new LinkedHashSet<Object>();
|
||||
|
||||
public static void add(RedisConnectionFactory factory) {
|
||||
connFactories.add(factory);
|
||||
}
|
||||
|
||||
public static void add(Object factory) {
|
||||
connFactories.add(factory);
|
||||
}
|
||||
|
||||
public static void cleanUp() {
|
||||
if (connFactories != null) {
|
||||
for (RedisConnectionFactory connectionFactory : connFactories) {
|
||||
for (Object connectionFactory : connFactories) {
|
||||
try {
|
||||
((DisposableBean) connectionFactory).destroy();
|
||||
// System.out.println("Succesfully cleaned up factory " + connectionFactory);
|
||||
if (connectionFactory instanceof DisposableBean) {
|
||||
((DisposableBean) connectionFactory).destroy();
|
||||
// System.out.println("Succesfully cleaned up factory " + connectionFactory);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Cannot clean factory " + connectionFactory + ex);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class PrefixStringObjectFactory implements ObjectFactory<String> {
|
||||
|
||||
private final String prefix;
|
||||
private final ObjectFactory<String> delegate;
|
||||
|
||||
public PrefixStringObjectFactory(String prefix, ObjectFactory<String> delegate) {
|
||||
|
||||
this.prefix = prefix;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String instance() {
|
||||
return prefix.concat(delegate.instance());
|
||||
}
|
||||
}
|
||||
@@ -15,11 +15,18 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.collection.IsCollectionWithSize.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
import reactor.test.TestSubscriber;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -28,12 +35,13 @@ import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.TestSubscriber;
|
||||
import com.lambdaworks.redis.SetArgs;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link LettuceReactiveKeyCommands}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class LettuceReactiveKeyCommandsTests extends LettuceReactiveCommandsTestsBase {
|
||||
|
||||
@@ -181,4 +189,112 @@ public class LettuceReactiveKeyCommandsTests extends LettuceReactiveCommandsTest
|
||||
subscriber.assertValueCount(2);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldExpireKeysCorrectly() {
|
||||
|
||||
nativeCommands.set(KEY_1, VALUE_1);
|
||||
|
||||
StepVerifier.create(connection.keyCommands().expire(KEY_1_BBUFFER, Duration.ofSeconds(10))) //
|
||||
.expectNext(true) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
|
||||
assertThat(nativeCommands.ttl(KEY_1), is(greaterThan(8L)));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldPreciseExpireKeysCorrectly() {
|
||||
|
||||
nativeCommands.set(KEY_1, VALUE_1);
|
||||
|
||||
StepVerifier.create(connection.keyCommands().pExpire(KEY_1_BBUFFER, Duration.ofSeconds(10))) //
|
||||
.expectNext(true) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
|
||||
assertThat(nativeCommands.ttl(KEY_1), is(greaterThan(8L)));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldExpireAtKeysCorrectly() {
|
||||
|
||||
nativeCommands.set(KEY_1, VALUE_1);
|
||||
Instant expireAt = Instant.now().plus(Duration.ofSeconds(10));
|
||||
|
||||
StepVerifier.create(connection.keyCommands().expireAt(KEY_1_BBUFFER, expireAt)) //
|
||||
.expectNext(true) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
|
||||
assertThat(nativeCommands.ttl(KEY_1), is(greaterThan(8L)));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldPreciseExpireAtKeysCorrectly() {
|
||||
|
||||
nativeCommands.set(KEY_1, VALUE_1);
|
||||
Instant expireAt = Instant.now().plus(Duration.ofSeconds(10));
|
||||
|
||||
StepVerifier.create(connection.keyCommands().pExpireAt(KEY_1_BBUFFER, expireAt)) //
|
||||
.expectNext(true) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
|
||||
assertThat(nativeCommands.ttl(KEY_1), is(greaterThan(8L)));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldReportTimeToLiveCorrectly() {
|
||||
|
||||
nativeCommands.set(KEY_1, VALUE_1, SetArgs.Builder.ex(10));
|
||||
|
||||
StepVerifier.create(connection.keyCommands().ttl(KEY_1_BBUFFER)) //
|
||||
.expectNextMatches(actual -> {
|
||||
assertThat(nativeCommands.ttl(KEY_1), is(greaterThan(8L)));
|
||||
return true;
|
||||
}) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldReportPreciseTimeToLiveCorrectly() {
|
||||
|
||||
nativeCommands.set(KEY_1, VALUE_1, SetArgs.Builder.ex(10));
|
||||
|
||||
StepVerifier.create(connection.keyCommands().pTtl(KEY_1_BBUFFER)) //
|
||||
.expectNextMatches(actual -> {
|
||||
assertThat(actual, is(greaterThan(8000L)));
|
||||
return true;
|
||||
}) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldPersist() {
|
||||
|
||||
nativeCommands.set(KEY_1, VALUE_1, SetArgs.Builder.ex(10));
|
||||
|
||||
StepVerifier.create(connection.keyCommands().persist(KEY_1_BBUFFER)) //
|
||||
.expectNext(true) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
|
||||
assertThat(nativeCommands.ttl(KEY_1), is(-1L));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldMoveToDatabase() {
|
||||
|
||||
assumeThat(connection, is(not(instanceOf(LettuceReactiveRedisClusterConnection.class))));
|
||||
|
||||
nativeCommands.set(KEY_1, VALUE_1);
|
||||
|
||||
StepVerifier.create(connection.keyCommands().move(KEY_1_BBUFFER, 5)) //
|
||||
.expectNext(true) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
assertThat(nativeCommands.exists(KEY_1), is(0L));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import static org.hamcrest.core.Is.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
@@ -200,7 +200,7 @@ public class LettuceReactiveZSetCommandsTests extends LettuceReactiveCommandsTes
|
||||
nativeCommands.zadd(KEY_1, 2D, VALUE_2);
|
||||
nativeCommands.zadd(KEY_1, 3D, VALUE_3);
|
||||
|
||||
assertThat(connection.zSetCommands().zRevRangeByScore(KEY_1_BBUFFER, new Range<>(3D, 2D)).block(),
|
||||
assertThat(connection.zSetCommands().zRevRangeByScore(KEY_1_BBUFFER, new Range<>(2D, 3D)).block(),
|
||||
IsIterableContainingInOrder.contains(VALUE_3_BBUFFER, VALUE_2_BBUFFER));
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ public class LettuceReactiveZSetCommandsTests extends LettuceReactiveCommandsTes
|
||||
nativeCommands.zadd(KEY_1, 2D, VALUE_2);
|
||||
nativeCommands.zadd(KEY_1, 3D, VALUE_3);
|
||||
|
||||
assertThat(connection.zSetCommands().zRevRangeByScore(KEY_1_BBUFFER, new Range<>(3D, 2D, true, false)).block(),
|
||||
assertThat(connection.zSetCommands().zRevRangeByScore(KEY_1_BBUFFER, new Range<>(2D, 3D, false, true)).block(),
|
||||
IsIterableContainingInOrder.contains(VALUE_3_BBUFFER));
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ public class LettuceReactiveZSetCommandsTests extends LettuceReactiveCommandsTes
|
||||
nativeCommands.zadd(KEY_1, 2D, VALUE_2);
|
||||
nativeCommands.zadd(KEY_1, 3D, VALUE_3);
|
||||
|
||||
assertThat(connection.zSetCommands().zRevRangeByScore(KEY_1_BBUFFER, new Range<>(3D, 2D, false, true)).block(),
|
||||
assertThat(connection.zSetCommands().zRevRangeByScore(KEY_1_BBUFFER, new Range<>(2D, 3D, true, false)).block(),
|
||||
IsIterableContainingInOrder.contains(VALUE_2_BBUFFER));
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ public class LettuceReactiveZSetCommandsTests extends LettuceReactiveCommandsTes
|
||||
nativeCommands.zadd(KEY_1, 2D, VALUE_2);
|
||||
nativeCommands.zadd(KEY_1, 3D, VALUE_3);
|
||||
|
||||
assertThat(connection.zSetCommands().zRevRangeByScoreWithScores(KEY_1_BBUFFER, new Range<>(3D, 2D)).block(),
|
||||
assertThat(connection.zSetCommands().zRevRangeByScoreWithScores(KEY_1_BBUFFER, new Range<>(2D, 3D)).block(),
|
||||
IsIterableContainingInOrder.contains(new DefaultTuple(VALUE_3_BBUFFER.array(), 3D),
|
||||
new DefaultTuple(VALUE_2_BBUFFER.array(), 2D)));
|
||||
}
|
||||
@@ -246,7 +246,7 @@ public class LettuceReactiveZSetCommandsTests extends LettuceReactiveCommandsTes
|
||||
nativeCommands.zadd(KEY_1, 3D, VALUE_3);
|
||||
|
||||
assertThat(
|
||||
connection.zSetCommands().zRevRangeByScoreWithScores(KEY_1_BBUFFER, new Range<>(3D, 2D, true, false)).block(),
|
||||
connection.zSetCommands().zRevRangeByScoreWithScores(KEY_1_BBUFFER, new Range<>(2D, 3D, false, true)).block(),
|
||||
IsIterableContainingInOrder.contains(new DefaultTuple(VALUE_3_BBUFFER.array(), 3D)));
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ public class LettuceReactiveZSetCommandsTests extends LettuceReactiveCommandsTes
|
||||
nativeCommands.zadd(KEY_1, 3D, VALUE_3);
|
||||
|
||||
assertThat(
|
||||
connection.zSetCommands().zRevRangeByScoreWithScores(KEY_1_BBUFFER, new Range<>(3D, 2D, false, true)).block(),
|
||||
connection.zSetCommands().zRevRangeByScoreWithScores(KEY_1_BBUFFER, new Range<>(2D, 3D, true, false)).block(),
|
||||
IsIterableContainingInOrder.contains(new DefaultTuple(VALUE_2_BBUFFER.array(), 2D)));
|
||||
}
|
||||
|
||||
@@ -466,14 +466,14 @@ public class LettuceReactiveZSetCommandsTests extends LettuceReactiveCommandsTes
|
||||
nativeCommands.zadd(KEY_1, 0D, "f");
|
||||
nativeCommands.zadd(KEY_1, 0D, "g");
|
||||
|
||||
assertThat(connection.zSetCommands().zRevRangeByLex(KEY_1_BBUFFER, new Range<>("c", "")).block(),
|
||||
assertThat(connection.zSetCommands().zRevRangeByLex(KEY_1_BBUFFER, new Range<>("", "c")).block(),
|
||||
IsIterableContainingInOrder.contains(ByteBuffer.wrap("c".getBytes()), ByteBuffer.wrap("b".getBytes()),
|
||||
ByteBuffer.wrap("a".getBytes())));
|
||||
|
||||
assertThat(connection.zSetCommands().zRevRangeByLex(KEY_1_BBUFFER, new Range<>("c", "", false, true)).block(),
|
||||
assertThat(connection.zSetCommands().zRevRangeByLex(KEY_1_BBUFFER, new Range<>("", "c", true, false)).block(),
|
||||
IsIterableContainingInOrder.contains(ByteBuffer.wrap("b".getBytes()), ByteBuffer.wrap("a".getBytes())));
|
||||
|
||||
assertThat(connection.zSetCommands().zRevRangeByLex(KEY_1_BBUFFER, new Range<>("g", "aaa", false, true)).block(),
|
||||
assertThat(connection.zSetCommands().zRevRangeByLex(KEY_1_BBUFFER, new Range<>("aaa", "g", true, false)).block(),
|
||||
IsIterableContainingInOrder.contains(ByteBuffer.wrap("f".getBytes()), ByteBuffer.wrap("e".getBytes()),
|
||||
ByteBuffer.wrap("d".getBytes()), ByteBuffer.wrap("c".getBytes()), ByteBuffer.wrap("b".getBytes())));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
|
||||
import org.springframework.data.redis.test.util.MinimumRedisVersionRule;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultReactiveGeoOperations}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "3.2.0+")
|
||||
public class DefaultReactiveGeoOperationsIntegrationTests<K, V> {
|
||||
|
||||
public static @ClassRule MinimumRedisVersionRule versionRule = new MinimumRedisVersionRule();
|
||||
|
||||
private static final Point POINT_ARIGENTO = new Point(13.583333, 37.316667);
|
||||
private static final Point POINT_CATANIA = new Point(15.087269, 37.502669);
|
||||
private static final Point POINT_PALERMO = new Point(13.361389, 38.115556);
|
||||
|
||||
private static final double DISTANCE_PALERMO_CATANIA_METERS = 166274.15156960033;
|
||||
private static final double DISTANCE_PALERMO_CATANIA_KILOMETERS = 166.27415156960033;
|
||||
|
||||
private final ReactiveRedisTemplate<K, V> redisTemplate;
|
||||
private final ReactiveGeoOperations<K, V> geoOperations;
|
||||
|
||||
private final ObjectFactory<K> keyFactory;
|
||||
private final ObjectFactory<V> valueFactory;
|
||||
|
||||
@Parameters(name = "{3}")
|
||||
public static Collection<Object[]> testParams() {
|
||||
return ReactiveOperationsTestParams.testParams();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
ConnectionFactoryTracker.cleanUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redisTemplate
|
||||
* @param keyFactory
|
||||
* @param valueFactory
|
||||
* @param label parameterized test label, no further use besides that.
|
||||
*/
|
||||
public DefaultReactiveGeoOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
|
||||
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
|
||||
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.geoOperations = redisTemplate.opsForGeo();
|
||||
this.keyFactory = keyFactory;
|
||||
this.valueFactory = valueFactory;
|
||||
|
||||
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
RedisConnectionFactory connectionFactory = (RedisConnectionFactory) redisTemplate.getConnectionFactory();
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
connection.flushAll();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoAdd() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(geoOperations.geoAdd(key, POINT_PALERMO, value)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoAddLocation() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(geoOperations.geoAdd(key, new GeoLocation<>(value, POINT_PALERMO))) //
|
||||
.expectNext(1L) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoAddMapOfLocations() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
Map<V, Point> memberCoordinateMap = new HashMap<>();
|
||||
memberCoordinateMap.put(valueFactory.instance(), POINT_PALERMO);
|
||||
memberCoordinateMap.put(valueFactory.instance(), POINT_CATANIA);
|
||||
|
||||
StepVerifier.create(geoOperations.geoAdd(key, memberCoordinateMap)).expectNext(2L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoAddIterableOfLocations() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
List<GeoLocation<V>> geoLocations = Arrays.asList(new GeoLocation<>(valueFactory.instance(), POINT_ARIGENTO),
|
||||
new GeoLocation<>(valueFactory.instance(), POINT_PALERMO));
|
||||
|
||||
StepVerifier.create(geoOperations.geoAdd(key, geoLocations)).expectNext(2L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoAddPublisherOfLocations() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
List<GeoLocation<V>> batch1 = Arrays.asList(new GeoLocation<>(valueFactory.instance(), POINT_ARIGENTO),
|
||||
new GeoLocation<>(valueFactory.instance(), POINT_PALERMO));
|
||||
|
||||
List<GeoLocation<V>> batch2 = Arrays.asList(new GeoLocation<>(valueFactory.instance(), POINT_CATANIA));
|
||||
|
||||
Flux<List<GeoLocation<V>>> geoLocations = Flux.just(batch1, batch2);
|
||||
|
||||
StepVerifier.create(geoOperations.geoAdd(key, geoLocations)).expectNext(2L).expectNext(1L).expectComplete()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoDistShouldReturnDistanceInMetersByDefault() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
V member2 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, member2).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoDist(key, member1, member2)).consumeNextWith(actual -> {
|
||||
|
||||
assertThat(actual.getValue()).isCloseTo(DISTANCE_PALERMO_CATANIA_METERS, offset(0.005));
|
||||
assertThat(actual.getUnit()).isEqualTo("m");
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoDistShouldReturnDistanceInKilometersCorrectly() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
V member2 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, member2).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoDist(key, member1, member2, Metrics.KILOMETERS)).consumeNextWith(actual -> {
|
||||
|
||||
assertThat(actual.getValue()).isCloseTo(DISTANCE_PALERMO_CATANIA_KILOMETERS, offset(0.005));
|
||||
assertThat(actual.getUnit()).isEqualTo("km");
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoHash() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, v1).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoHash(key, v1)) //
|
||||
.expectNext("sqc8b49rny0") //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoHashShouldReturnMultipleElements() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
V v2 = valueFactory.instance();
|
||||
V v3 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, v1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, v2).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoHash(key, v1, v3, v2)) //
|
||||
.expectNext(Arrays.asList("sqc8b49rny0", null, "sqdtr74hyu0")) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoPos() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, v1).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoPos(key, v1)) //
|
||||
.consumeNextWith(actual -> {
|
||||
|
||||
assertThat(actual.getX()).isCloseTo(POINT_PALERMO.getX(), offset(0.005));
|
||||
assertThat(actual.getY()).isCloseTo(POINT_PALERMO.getY(), offset(0.005));
|
||||
}).expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoPosShouldReturnMultipleElements() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
V v2 = valueFactory.instance();
|
||||
V v3 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, v1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, v2).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoPos(key, v1, v3, v2)) //
|
||||
.consumeNextWith(actual -> {
|
||||
|
||||
assertThat(actual.get(0).getX()).isCloseTo(POINT_PALERMO.getX(), offset(0.005));
|
||||
assertThat(actual.get(0).getY()).isCloseTo(POINT_PALERMO.getY(), offset(0.005));
|
||||
|
||||
assertThat(actual.get(1)).isNull();
|
||||
assertThat(actual.get(2)).isNotNull();
|
||||
}).expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-438
|
||||
public void geoRadius() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
V member2 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, member2).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoRadius(key, new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS))))
|
||||
.consumeNextWith(actual -> assertThat(actual).hasSize(2)).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoRadiusShouldReturnLocationsWithDistance() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
V member2 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, member2).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoRadius(key, new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)),
|
||||
newGeoRadiusArgs().includeDistance().sortDescending())).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(2);
|
||||
|
||||
assertThat(actual.getContent().get(0).getDistance().getValue()).isCloseTo(190.4424d, offset(0.005));
|
||||
assertThat(actual.getContent().get(0).getContent().getName()).isEqualTo(member1);
|
||||
|
||||
assertThat(actual.getContent().get(1).getDistance().getValue()).isCloseTo(56.4413d, offset(0.005));
|
||||
assertThat(actual.getContent().get(1).getContent().getName()).isEqualTo(member2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-438
|
||||
public void geoRadiusByMemberShouldReturnMembersCorrectly() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
V member2 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, member2).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoRadius(key, new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS))))
|
||||
.consumeNextWith(actual -> assertThat(actual).hasSize(2)) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoRadiusByMemberWithin100_000MetersShouldReturnLocations() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
V member2 = valueFactory.instance();
|
||||
V member3 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, member2).block();
|
||||
geoOperations.geoAdd(key, POINT_ARIGENTO, member3).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoRadiusByMember(key, member3, 100_000)) //
|
||||
.consumeNextWith(actual -> {
|
||||
|
||||
assertThat(actual).hasSize(2);
|
||||
|
||||
assertThat(actual.get(0).getName()).isEqualTo(member3);
|
||||
assertThat(actual.get(1).getName()).isEqualTo(member1);
|
||||
}) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoRadiusByMemberWithin100KMShouldReturnLocations() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
V member2 = valueFactory.instance();
|
||||
V member3 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, member2).block();
|
||||
geoOperations.geoAdd(key, POINT_ARIGENTO, member3).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoRadiusByMember(key, member3, new Distance(100D, KILOMETERS)))
|
||||
.consumeNextWith(actual -> {
|
||||
|
||||
assertThat(actual).hasSize(2);
|
||||
|
||||
assertThat(actual.get(0).getName()).isEqualTo(member3);
|
||||
assertThat(actual.get(1).getName()).isEqualTo(member1);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoRadiusByMemberShouldReturnLocationsWithDistance() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
V member2 = valueFactory.instance();
|
||||
V member3 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, member2).block();
|
||||
geoOperations.geoAdd(key, POINT_ARIGENTO, member3).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoRadiusByMember(key, member3, new Distance(100D, KILOMETERS),
|
||||
newGeoRadiusArgs().includeDistance().sortDescending())).consumeNextWith(actual -> {
|
||||
|
||||
assertThat(actual).hasSize(2);
|
||||
|
||||
assertThat(actual.getContent().get(0).getDistance().getValue()).isCloseTo(90.9778, offset(0.005));
|
||||
assertThat(actual.getContent().get(0).getContent().getName()).isEqualTo(member1);
|
||||
|
||||
assertThat(actual.getContent().get(1).getDistance().getValue()).isCloseTo(0.0, offset(0.005));
|
||||
assertThat(actual.getContent().get(1).getContent().getName()).isEqualTo(member3);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void geoRemove() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
V member2 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
geoOperations.geoAdd(key, POINT_CATANIA, member2).block();
|
||||
|
||||
StepVerifier.create(geoOperations.geoRemove(key, member1)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(geoOperations.geoPos(key, member1)).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void delete() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V member1 = valueFactory.instance();
|
||||
|
||||
geoOperations.geoAdd(key, POINT_PALERMO, member1).block();
|
||||
|
||||
StepVerifier.create(geoOperations.delete(key)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(geoOperations.geoPos(key, member1)).verifyComplete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.RawObjectFactory;
|
||||
import org.springframework.data.redis.SettingsUtils;
|
||||
import org.springframework.data.redis.StringObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultReactiveHashOperations}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class DefaultReactiveHashOperationsIntegrationTests<K, HK, HV> {
|
||||
|
||||
private final ReactiveRedisTemplate<K, ?> redisTemplate;
|
||||
private final ReactiveHashOperations<K, HK, HV> hashOperations;
|
||||
|
||||
private final ObjectFactory<K> keyFactory;
|
||||
private final ObjectFactory<HK> hashKeyFactory;
|
||||
private final ObjectFactory<HV> hashValueFactory;
|
||||
|
||||
@Parameters(name = "{4}")
|
||||
public static Collection<Object[]> testParams() {
|
||||
|
||||
ObjectFactory<String> stringFactory = new StringObjectFactory();
|
||||
ObjectFactory<byte[]> rawFactory = new RawObjectFactory();
|
||||
|
||||
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory();
|
||||
lettuceConnectionFactory.setPort(SettingsUtils.getPort());
|
||||
lettuceConnectionFactory.setHostName(SettingsUtils.getHost());
|
||||
lettuceConnectionFactory.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<String, String> stringTemplate = new ReactiveRedisTemplate<>();
|
||||
stringTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
stringTemplate.setEnableDefaultSerializer(true);
|
||||
stringTemplate.setDefaultSerializer(new StringRedisSerializer());
|
||||
stringTemplate.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<byte[], byte[]> rawTemplate = new ReactiveRedisTemplate<>();
|
||||
rawTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
rawTemplate.setEnableDefaultSerializer(false);
|
||||
rawTemplate.afterPropertiesSet();
|
||||
|
||||
return Arrays.asList(new Object[][] { { stringTemplate, stringFactory, stringFactory, stringFactory, "String" },
|
||||
{ rawTemplate, rawFactory, rawFactory, rawFactory, "raw" } });
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
ConnectionFactoryTracker.cleanUp();
|
||||
}
|
||||
|
||||
public DefaultReactiveHashOperationsIntegrationTests(ReactiveRedisTemplate<K, ?> redisTemplate,
|
||||
ObjectFactory<K> keyFactory, ObjectFactory<HK> hashKeyFactory, ObjectFactory<HV> hashValueFactory,
|
||||
String testName) {
|
||||
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.hashOperations = redisTemplate.opsForHash();
|
||||
this.keyFactory = keyFactory;
|
||||
this.hashKeyFactory = hashKeyFactory;
|
||||
this.hashValueFactory = hashValueFactory;
|
||||
|
||||
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
RedisConnectionFactory connectionFactory = (RedisConnectionFactory) redisTemplate.getConnectionFactory();
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
connection.flushAll();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void remove() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey1 = hashKeyFactory.instance();
|
||||
HV hashvalue1 = hashValueFactory.instance();
|
||||
|
||||
HK hashkey2 = hashKeyFactory.instance();
|
||||
HV hashvalue2 = hashValueFactory.instance();
|
||||
|
||||
putAll(key, hashkey1, hashvalue1, hashkey2, hashvalue2);
|
||||
StepVerifier.create(hashOperations.remove(key, hashkey1, hashkey2)).expectNext(2L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void hasKey() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey = hashKeyFactory.instance();
|
||||
HV hashvalue = hashValueFactory.instance();
|
||||
|
||||
StepVerifier.create(hashOperations.put(key, hashkey, hashvalue)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(hashOperations.hasKey(key, hashkey)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(hashOperations.hasKey(key, hashKeyFactory.instance())).expectNext(false).expectComplete()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void get() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey = hashKeyFactory.instance();
|
||||
HV hashvalue = hashValueFactory.instance();
|
||||
|
||||
StepVerifier.create(hashOperations.put(key, hashkey, hashvalue)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(hashOperations.get(key, hashkey)).expectNextCount(1).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void multiGet() {
|
||||
|
||||
assumeTrue(hashKeyFactory instanceof StringObjectFactory && hashValueFactory instanceof StringObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey1 = hashKeyFactory.instance();
|
||||
HV hashvalue1 = hashValueFactory.instance();
|
||||
|
||||
HK hashkey2 = hashKeyFactory.instance();
|
||||
HV hashvalue2 = hashValueFactory.instance();
|
||||
|
||||
putAll(key, hashkey1, hashvalue1, hashkey2, hashvalue2);
|
||||
|
||||
StepVerifier.create(hashOperations.multiGet(key, Arrays.asList(hashkey1, hashkey2))).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(2).containsSequence(hashvalue1, hashvalue2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void increment() {
|
||||
|
||||
assumeTrue(hashValueFactory instanceof StringObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey = hashKeyFactory.instance();
|
||||
HV hashvalue = (HV) "1";
|
||||
|
||||
StepVerifier.create(hashOperations.put(key, hashkey, hashvalue)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(hashOperations.increment(key, hashkey, 1L)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(hashOperations.get(key, hashkey)).expectNext((HV) "2").verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
@SuppressWarnings("unchecked")
|
||||
public void incrementDouble() {
|
||||
|
||||
assumeTrue(hashValueFactory instanceof StringObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey = hashKeyFactory.instance();
|
||||
HV hashvalue = (HV) "1";
|
||||
|
||||
StepVerifier.create(hashOperations.put(key, hashkey, hashvalue)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(hashOperations.increment(key, hashkey, 1.1d)).expectNext(2.1d).verifyComplete();
|
||||
StepVerifier.create(hashOperations.get(key, hashkey)).expectNext((HV) "2.1").verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void keys() {
|
||||
|
||||
assumeTrue(hashKeyFactory instanceof StringObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey1 = hashKeyFactory.instance();
|
||||
HV hashvalue1 = hashValueFactory.instance();
|
||||
|
||||
HK hashkey2 = hashKeyFactory.instance();
|
||||
HV hashvalue2 = hashValueFactory.instance();
|
||||
|
||||
putAll(key, hashkey1, hashvalue1, hashkey2, hashvalue2);
|
||||
|
||||
StepVerifier.create(hashOperations.keys(key)).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(2).contains(hashkey1, hashkey2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void size() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey1 = hashKeyFactory.instance();
|
||||
HV hashvalue1 = hashValueFactory.instance();
|
||||
|
||||
HK hashkey2 = hashKeyFactory.instance();
|
||||
HV hashvalue2 = hashValueFactory.instance();
|
||||
|
||||
putAll(key, hashkey1, hashvalue1, hashkey2, hashvalue2);
|
||||
|
||||
StepVerifier.create(hashOperations.size(key)).expectNext(2L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void putAll() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey1 = hashKeyFactory.instance();
|
||||
HV hashvalue1 = hashValueFactory.instance();
|
||||
|
||||
HK hashkey2 = hashKeyFactory.instance();
|
||||
HV hashvalue2 = hashValueFactory.instance();
|
||||
|
||||
putAll(key, hashkey1, hashvalue1, hashkey2, hashvalue2);
|
||||
|
||||
StepVerifier.create(hashOperations.hasKey(key, hashkey1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(hashOperations.hasKey(key, hashkey2)).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void put() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey = hashKeyFactory.instance();
|
||||
HV hashvalue = hashValueFactory.instance();
|
||||
|
||||
StepVerifier.create(hashOperations.put(key, hashkey, hashvalue)).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void putIfAbsent() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey = hashKeyFactory.instance();
|
||||
HV hashvalue = hashValueFactory.instance();
|
||||
HV hashvalue2 = hashValueFactory.instance();
|
||||
|
||||
StepVerifier.create(hashOperations.putIfAbsent(key, hashkey, hashvalue)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(hashOperations.putIfAbsent(key, hashkey, hashvalue2)).expectNext(false).expectComplete()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void values() {
|
||||
|
||||
assumeTrue(hashValueFactory instanceof StringObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey1 = hashKeyFactory.instance();
|
||||
HV hashvalue1 = hashValueFactory.instance();
|
||||
|
||||
HK hashkey2 = hashKeyFactory.instance();
|
||||
HV hashvalue2 = hashValueFactory.instance();
|
||||
|
||||
putAll(key, hashkey1, hashvalue1, hashkey2, hashvalue2);
|
||||
|
||||
StepVerifier.create(hashOperations.values(key)).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(2).contains(hashvalue1, hashvalue2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void entries() {
|
||||
|
||||
assumeTrue(hashKeyFactory instanceof StringObjectFactory && hashValueFactory instanceof StringObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey1 = hashKeyFactory.instance();
|
||||
HV hashvalue1 = hashValueFactory.instance();
|
||||
|
||||
HK hashkey2 = hashKeyFactory.instance();
|
||||
HV hashvalue2 = hashValueFactory.instance();
|
||||
|
||||
putAll(key, hashkey1, hashvalue1, hashkey2, hashvalue2);
|
||||
|
||||
StepVerifier.create(hashOperations.entries(key)).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(2).containsEntry(hashkey1, hashvalue1).containsEntry(hashkey2, hashvalue2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void delete() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
HK hashkey = hashKeyFactory.instance();
|
||||
HV hashvalue = hashValueFactory.instance();
|
||||
|
||||
StepVerifier.create(hashOperations.put(key, hashkey, hashvalue)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(hashOperations.delete(key)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(hashOperations.size(key)).expectNext(0L).verifyComplete();
|
||||
}
|
||||
|
||||
private void putAll(K key, HK hashkey1, HV hashvalue1, HK hashkey2, HV hashvalue2) {
|
||||
|
||||
Map<HK, HV> map = new HashMap<>();
|
||||
map.put(hashkey1, hashvalue1);
|
||||
map.put(hashkey2, hashvalue2);
|
||||
|
||||
StepVerifier.create(hashOperations.putAll(key, map)).expectNext(true).verifyComplete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultReactiveHyperLogLogOperations}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class DefaultReactiveHyperLogLogOperationsIntegrationTests<K, V> {
|
||||
|
||||
private final ReactiveRedisTemplate<K, V> redisTemplate;
|
||||
private final ReactiveHyperLogLogOperations<K, V> hyperLogLogOperations;
|
||||
|
||||
private final ObjectFactory<K> keyFactory;
|
||||
private final ObjectFactory<V> valueFactory;
|
||||
|
||||
@Parameters(name = "{3}")
|
||||
public static Collection<Object[]> testParams() {
|
||||
return ReactiveOperationsTestParams.testParams();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
ConnectionFactoryTracker.cleanUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redisTemplate
|
||||
* @param keyFactory
|
||||
* @param valueFactory
|
||||
* @param label parameterized test label, no further use besides that.
|
||||
*/
|
||||
public DefaultReactiveHyperLogLogOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
|
||||
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
|
||||
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.hyperLogLogOperations = redisTemplate.opsForHyperLogLog();
|
||||
this.keyFactory = keyFactory;
|
||||
this.valueFactory = valueFactory;
|
||||
|
||||
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
RedisConnectionFactory connectionFactory = (RedisConnectionFactory) redisTemplate.getConnectionFactory();
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
connection.flushAll();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void add() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(hyperLogLogOperations.add(key, value1, value2)).expectNext(1L).verifyComplete();
|
||||
|
||||
StepVerifier.create(hyperLogLogOperations.size(key)).expectNext(2L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void union() {
|
||||
|
||||
K mergedKey = keyFactory.instance();
|
||||
V sharedValue = valueFactory.instance();
|
||||
|
||||
K key1 = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
|
||||
K key2 = keyFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(hyperLogLogOperations.add(key1, value1, sharedValue)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(hyperLogLogOperations.add(key2, value2, sharedValue)).expectNext(1L).verifyComplete();
|
||||
|
||||
StepVerifier.create(hyperLogLogOperations.union(mergedKey, key1, key2)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(hyperLogLogOperations.size(mergedKey)).expectNext(3L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void delete() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(hyperLogLogOperations.add(key, value1, value2)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(hyperLogLogOperations.delete(key)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(hyperLogLogOperations.size(key)).expectNext(0L).verifyComplete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.data.redis.ByteBufferObjectFactory;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultReactiveListOperations}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class DefaultReactiveListOperationsIntegrationTests<K, V> {
|
||||
|
||||
private final ReactiveRedisTemplate<K, V> redisTemplate;
|
||||
private final ReactiveListOperations<K, V> listOperations;
|
||||
|
||||
private final ObjectFactory<K> keyFactory;
|
||||
private final ObjectFactory<V> valueFactory;
|
||||
|
||||
@Parameters(name = "{3}")
|
||||
public static Collection<Object[]> testParams() {
|
||||
return ReactiveOperationsTestParams.testParams();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
ConnectionFactoryTracker.cleanUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redisTemplate
|
||||
* @param keyFactory
|
||||
* @param valueFactory
|
||||
* @param label parameterized test label, no further use besides that.
|
||||
*/
|
||||
public DefaultReactiveListOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
|
||||
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
|
||||
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.listOperations = redisTemplate.opsForList();
|
||||
this.keyFactory = keyFactory;
|
||||
this.valueFactory = valueFactory;
|
||||
|
||||
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
RedisConnectionFactory connectionFactory = (RedisConnectionFactory) redisTemplate.getConnectionFactory();
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
connection.flushAll();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void trim() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.trim(key, 0, 0)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.size(key)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void size() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.size(key)).expectNext(0L).verifyComplete();
|
||||
StepVerifier.create(listOperations.rightPush(key, value1)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(listOperations.size(key)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void leftPush() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.leftPush(key, value1)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(listOperations.leftPush(key, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.range(key, 0, -1).flatMap(Flux::fromIterable)).expectNext(value2)
|
||||
.expectNext(value1).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void leftPushAll() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.leftPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.range(key, 0, -1).flatMap(Flux::fromIterable)).expectNext(value2)
|
||||
.expectNext(value1).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void leftPushIfPresent() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.leftPushIfPresent(key, value1)).expectNext(0L).verifyComplete();
|
||||
StepVerifier.create(listOperations.leftPush(key, value1)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(listOperations.leftPushIfPresent(key, value2)).expectNext(2L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void leftPushWithPivot() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
V value3 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.leftPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.leftPush(key, value1, value3)).expectNext(3L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.range(key, 0, -1).flatMap(Flux::fromIterable)).expectNext(value2)
|
||||
.expectNext(value3).expectNext(value1).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rightPush() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPush(key, value1)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(listOperations.rightPush(key, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.range(key, 0, -1).flatMap(Flux::fromIterable)).expectNext(value1)
|
||||
.expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rightPushAll() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.range(key, 0, -1).flatMap(Flux::fromIterable)).expectNext(value1)
|
||||
.expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rightPushIfPresent() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPushIfPresent(key, value1)).expectNext(0L).verifyComplete();
|
||||
StepVerifier.create(listOperations.rightPush(key, value1)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(listOperations.rightPushIfPresent(key, value2)).expectNext(2L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rightPushWithPivot() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
V value3 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.rightPush(key, value1, value3)).expectNext(3L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.range(key, 0, -1).flatMap(Flux::fromIterable)).expectNext(value1)
|
||||
.expectNext(value3).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void set() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.set(key, 1, value1)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.range(key, 0, -1).flatMap(Flux::fromIterable)).expectNext(value1)
|
||||
.expectNext(value1).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void remove() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.remove(key, 1, value1)).expectNext(1L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.range(key, 0, -1).flatMap(Flux::fromIterable)).expectNext(value2)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void index() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.index(key, 1)).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void leftPop() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.leftPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.leftPop(key)).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rightPop() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.rightPop(key)).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void leftPopWithTimeout() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.leftPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.leftPop(key, Duration.ZERO)).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) // DATAREDIS-602
|
||||
public void leftPopWithMillisecondTimeoutShouldFail() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
listOperations.leftPop(key, Duration.ofMillis(1001));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rightPopWithTimeout() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPushAll(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.rightPop(key, Duration.ZERO)).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rightPopAndLeftPush() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K source = keyFactory.instance();
|
||||
K target = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPush(source, value)).expectNext(1L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.rightPopAndLeftPush(source, target)).expectNext(value).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.size(source)).expectNext(0L).verifyComplete();
|
||||
StepVerifier.create(listOperations.size(target)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rightPopAndLeftPushWithTimeout() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K source = keyFactory.instance();
|
||||
K target = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPopAndLeftPush(source, target, Duration.ofSeconds(1))).expectComplete()
|
||||
.verify();
|
||||
|
||||
StepVerifier.create(listOperations.rightPush(source, value)).expectNext(1L).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.rightPopAndLeftPush(source, target, Duration.ZERO)).expectNext(value)
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.size(source)).expectNext(0L).verifyComplete();
|
||||
StepVerifier.create(listOperations.size(target)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void delete() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(listOperations.rightPush(key, value1)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(listOperations.delete(key)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(listOperations.size(key)).expectNext(0L).verifyComplete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.data.redis.ByteBufferObjectFactory;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultReactiveSetOperations}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class DefaultReactiveSetOperationsIntegrationTests<K, V> {
|
||||
|
||||
private final ReactiveRedisTemplate<K, V> redisTemplate;
|
||||
private final ReactiveSetOperations<K, V> setOperations;
|
||||
|
||||
private final ObjectFactory<K> keyFactory;
|
||||
private final ObjectFactory<V> valueFactory;
|
||||
|
||||
@Parameters(name = "{3}")
|
||||
public static Collection<Object[]> testParams() {
|
||||
return ReactiveOperationsTestParams.testParams();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
ConnectionFactoryTracker.cleanUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redisTemplate
|
||||
* @param keyFactory
|
||||
* @param valueFactory
|
||||
* @param label parameterized test label, no further use besides that.
|
||||
*/
|
||||
public DefaultReactiveSetOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
|
||||
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
|
||||
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.setOperations = redisTemplate.opsForSet();
|
||||
this.keyFactory = keyFactory;
|
||||
this.valueFactory = valueFactory;
|
||||
|
||||
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
RedisConnectionFactory connectionFactory = (RedisConnectionFactory) redisTemplate.getConnectionFactory();
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
connection.flushAll();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void add() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value1)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(setOperations.add(key, value1, value2)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void remove() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.size(key)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.remove(key, value2)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(setOperations.size(key)).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(setOperations.remove(key, value1, value2)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void pop() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.pop(key)).consumeNextWith(actual -> {
|
||||
assertThat(actual).isIn(value1, value2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void move() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.move(key, value1, otherKey)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.size(otherKey)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void isMember() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.isMember(key, value1)).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void intersect() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, onlyInKey, shared)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.add(otherKey, onlyInOtherKey, shared)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.intersect(key, otherKey)).consumeNextWith(actual -> {
|
||||
assertThat(actual).contains(shared);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void intersectAndStore() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
K destKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, onlyInKey, shared)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.add(otherKey, onlyInOtherKey, shared)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.intersectAndStore(key, otherKey, destKey)).expectNext(1L).expectComplete()
|
||||
.verify();
|
||||
|
||||
StepVerifier.create(setOperations.isMember(destKey, shared)).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void difference() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, onlyInKey, shared)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.add(otherKey, onlyInOtherKey, shared)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.difference(key, otherKey)).consumeNextWith(actual -> {
|
||||
assertThat(actual).contains(onlyInKey);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void differenceAndStore() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
K destKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, onlyInKey, shared)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.add(otherKey, onlyInOtherKey, shared)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.differenceAndStore(key, otherKey, destKey)).expectNext(1L).expectComplete()
|
||||
.verify();
|
||||
|
||||
StepVerifier.create(setOperations.isMember(destKey, onlyInKey)).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void union() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, onlyInKey, shared)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.add(otherKey, onlyInOtherKey, shared)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.union(key, otherKey)).consumeNextWith(actual -> {
|
||||
assertThat(actual).contains(onlyInKey, shared, onlyInOtherKey);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void unionAndStore() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
K destKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, onlyInKey, shared)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.add(otherKey, onlyInOtherKey, shared)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.unionAndStore(key, otherKey, destKey)).expectNext(3L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.isMember(destKey, onlyInKey)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(setOperations.isMember(destKey, shared)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(setOperations.isMember(destKey, onlyInOtherKey)).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void members() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
StepVerifier.create(setOperations.members(key)).expectNext(new HashSet<V>(Arrays.asList(value1, value2)))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void randomMember() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.randomMember(key)).consumeNextWith(actual -> {
|
||||
assertThat(actual).isIn(value1, value2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void randomMembers() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.randomMembers(key, 3)).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(3);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void distinctRandomMembers() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value1, value2)).expectNext(2L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.distinctRandomMembers(key, 2)).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void delete() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(setOperations.add(key, value)).expectNext(1L).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.delete(key)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(setOperations.size(key)).expectNext(0L).verifyComplete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultReactiveValueOperations}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class DefaultReactiveValueOperationsIntegrationTests<K, V> {
|
||||
|
||||
private final ReactiveRedisTemplate<K, V> redisTemplate;
|
||||
private final ReactiveValueOperations<K, V> valueOperations;
|
||||
|
||||
private final ObjectFactory<K> keyFactory;
|
||||
private final ObjectFactory<V> valueFactory;
|
||||
|
||||
@Parameters(name = "{3}")
|
||||
public static Collection<Object[]> testParams() {
|
||||
return ReactiveOperationsTestParams.testParams();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
ConnectionFactoryTracker.cleanUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redisTemplate
|
||||
* @param keyFactory
|
||||
* @param valueFactory
|
||||
* @param label parameterized test label, no further use besides that.
|
||||
*/
|
||||
public DefaultReactiveValueOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
|
||||
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
|
||||
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.valueOperations = redisTemplate.opsForValue();
|
||||
this.keyFactory = keyFactory;
|
||||
this.valueFactory = valueFactory;
|
||||
|
||||
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
RedisConnectionFactory connectionFactory = (RedisConnectionFactory) redisTemplate.getConnectionFactory();
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
connection.flushAll();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void set() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key)).expectNext(value).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void setWithExpiry() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value, Duration.ofSeconds(10))).expectNext(true).expectComplete()
|
||||
.verify();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key)).expectNext(value).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.getExpire(key)) //
|
||||
.consumeNextWith(actual -> assertThat(actual).isGreaterThan(Duration.ofSeconds(8))) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void setIfAbsent() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.setIfAbsent(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.setIfAbsent(key, value)).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void setIfPresent() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
V laterValue = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.setIfPresent(key, value)).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.setIfPresent(key, laterValue)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key)).expectNext(laterValue).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void multiSet() {
|
||||
|
||||
K key1 = keyFactory.instance();
|
||||
K key2 = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
Map<K, V> map = new LinkedHashMap<K, V>();
|
||||
map.put(key1, value1);
|
||||
map.put(key2, value2);
|
||||
|
||||
StepVerifier.create(valueOperations.multiSet(map)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key1)).expectNext(value1).verifyComplete();
|
||||
StepVerifier.create(valueOperations.get(key2)).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void multiSetIfAbsent() {
|
||||
|
||||
K key1 = keyFactory.instance();
|
||||
K key2 = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
Map<K, V> map = new LinkedHashMap<K, V>();
|
||||
|
||||
map.put(key1, value1);
|
||||
|
||||
StepVerifier.create(valueOperations.multiSetIfAbsent(map)).expectNext(true).verifyComplete();
|
||||
|
||||
map.put(key2, value2);
|
||||
StepVerifier.create(valueOperations.multiSetIfAbsent(map)).expectNext(false).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key1)).expectNext(value1).verifyComplete();
|
||||
StepVerifier.create(valueOperations.get(key2)).expectNextCount(0).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void get() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key)).expectNext(value).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void getAndSet() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
V nextValue = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.getAndSet(key, nextValue)).expectNext(value).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key)).expectNext(nextValue).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void multiGet() {
|
||||
|
||||
K key1 = keyFactory.instance();
|
||||
K key2 = keyFactory.instance();
|
||||
K absent = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
V absentValue = null;
|
||||
|
||||
if (redisTemplate.getValueSerializer() instanceof StringRedisSerializer) {
|
||||
absentValue = (V) "";
|
||||
}
|
||||
if (value1 instanceof ByteBuffer) {
|
||||
absentValue = (V) ByteBuffer.wrap(new byte[0]);
|
||||
}
|
||||
|
||||
Map<K, V> map = new LinkedHashMap<K, V>();
|
||||
map.put(key1, value1);
|
||||
map.put(key2, value2);
|
||||
|
||||
StepVerifier.create(valueOperations.multiSet(map)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.multiGet(Arrays.asList(key2, key1, absent)))
|
||||
.expectNext(Arrays.asList(value2, value1, absentValue)).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void append() {
|
||||
|
||||
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.append(key, "foo")).expectNextCount(1).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key)).expectNext((V) (value + "foo")).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void getRange() {
|
||||
|
||||
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
String substring = value.toString().substring(1, 5);
|
||||
|
||||
StepVerifier.create(valueOperations.get(key, 1, 4)).expectNext(substring).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void setRange() {
|
||||
|
||||
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(valueOperations.set(key, (V) "boo", 2)).expectNextCount(1).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key)).consumeNextWith(actual -> {
|
||||
|
||||
String string = (String) actual;
|
||||
String prefix = value.toString().substring(0, 2);
|
||||
|
||||
assertThat(string).startsWith(prefix + "boo");
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void size() {
|
||||
|
||||
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(valueOperations.size(key)).expectNext((long) value.toString().length()).expectComplete()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void setBit() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.setBit(key, 0, true)).expectNext(false).expectComplete();
|
||||
StepVerifier.create(valueOperations.setBit(key, 2, true)).expectNext(false).expectComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void getBit() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.setBit(key, 0, true)).expectNext(false).expectComplete();
|
||||
StepVerifier.create(valueOperations.getBit(key, 0)).expectNext(true).expectComplete();
|
||||
StepVerifier.create(valueOperations.getBit(key, 1)).expectNext(false).expectComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void delete() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.delete(key)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.size(key)).expectNext(0L).verifyComplete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,617 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.redis.ByteBufferObjectFactory;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultReactiveZSetOperations}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
|
||||
|
||||
private final ReactiveRedisTemplate<K, V> redisTemplate;
|
||||
private final ReactiveZSetOperations<K, V> zSetOperations;
|
||||
|
||||
private final ObjectFactory<K> keyFactory;
|
||||
private final ObjectFactory<V> valueFactory;
|
||||
|
||||
@Parameters(name = "{3}")
|
||||
public static Collection<Object[]> testParams() {
|
||||
return ReactiveOperationsTestParams.testParams();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
ConnectionFactoryTracker.cleanUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redisTemplate
|
||||
* @param keyFactory
|
||||
* @param valueFactory
|
||||
* @param label parameterized test label, no further use besides that.
|
||||
*/
|
||||
public DefaultReactiveZSetOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
|
||||
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
|
||||
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.zSetOperations = redisTemplate.opsForZSet();
|
||||
this.keyFactory = keyFactory;
|
||||
this.valueFactory = valueFactory;
|
||||
|
||||
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
RedisConnectionFactory connectionFactory = (RedisConnectionFactory) redisTemplate.getConnectionFactory();
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
connection.flushAll();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void add() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value, 42.1)).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void addAll() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
List<DefaultTypedTuple<V>> tuples = Arrays.asList(new DefaultTypedTuple<>(value1, 42.1d),
|
||||
new DefaultTypedTuple<>(value2, 10d));
|
||||
|
||||
StepVerifier.create(zSetOperations.addAll(key, tuples)).expectNext(2L).verifyComplete();
|
||||
|
||||
List<DefaultTypedTuple<V>> updated = Arrays.asList(new DefaultTypedTuple<>(value1, 52.1d),
|
||||
new DefaultTypedTuple<>(value2, 10d));
|
||||
|
||||
StepVerifier.create(zSetOperations.addAll(key, updated)).expectNext(0L).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.score(key, value1)).expectNext(52.1d).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void remove() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value, 42.1)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.remove(key, value)).expectNext(1L).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.remove(key, value)).expectNext(0L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void incrementScore() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value, 42.1)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.incrementScore(key, value, 1.1)).expectNext(43.2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rank() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.rank(key, value1)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void reverseRank() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.reverseRank(key, value1)).expectNext(0L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void range() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.range(key, new Range<>(0L, 0L))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(value2);
|
||||
}).verifyComplete();
|
||||
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rangeWithScores() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.rangeWithScores(key, new Range<>(0L, 0L))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(new DefaultTypedTuple<>(value2, 10d));
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rangeByScore() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.rangeByScore(key, new Range<>(9d, 11d))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(value2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rangeByScoreWithScores() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.rangeByScoreWithScores(key, new Range<>(9d, 11d))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(new DefaultTypedTuple<>(value2, 10d));
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rangeByScoreWithLimit() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier
|
||||
.create(zSetOperations.rangeByScore(key, new Range<>(0d, 100d), //
|
||||
Limit.limit().offset(1).count(10))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(value1);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rangeByScoreWithScoresWithLimit() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier
|
||||
.create(zSetOperations.rangeByScoreWithScores(key, new Range<>(0d, 100d), //
|
||||
Limit.limit().offset(1).count(10))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(new DefaultTypedTuple<>(value1, 42.1));
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void reverseRange() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.reverseRange(key, new Range<>(0L, 0L))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(value1);
|
||||
}).verifyComplete();
|
||||
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void reverseRangeWithScores() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.reverseRangeWithScores(key, new Range<>(0L, 0L))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(new DefaultTypedTuple<>(value1, 42.1));
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void reverseRangeByScore() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.reverseRangeByScore(key, new Range<>(9d, 11d))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(value2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void reverseRangeByScoreWithScores() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.reverseRangeByScoreWithScores(key, new Range<>(9d, 11d))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(new DefaultTypedTuple<V>(value2, 10d));
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void reverseRangeByScoreWithLimit() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier
|
||||
.create(zSetOperations.reverseRangeByScore(key, new Range<>(0d, 100d), //
|
||||
Limit.limit().offset(1).count(10))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(value2);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void reverseRangeByScoreWithScoresWithLimit() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier
|
||||
.create(zSetOperations.reverseRangeByScoreWithScores(key, new Range<>(0d, 100d), //
|
||||
Limit.limit().offset(1).count(10))) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(new DefaultTypedTuple<>(value2, 10d));
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void count() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.count(key, new Range<Double>(0d, 100d))).expectNext(2L).expectComplete()
|
||||
.verify();
|
||||
StepVerifier.create(zSetOperations.count(key, new Range<Double>(0d, 10d))).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void size() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.size(key)).expectNext(2L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void score() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.score(key, value1)).expectNext(42.1d).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.score(key, value2)).expectNext(10d).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void removeRange() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.removeRange(key, new Range<>(0L, 0L))).expectNext(1L).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.range(key, new Range<>(0L, 5L))).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(value1);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void removeRangeByScore() {
|
||||
|
||||
assumeFalse(valueFactory instanceof ByteBufferObjectFactory);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value1, 42.1)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, value2, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.removeRangeByScore(key, new Range<>(9d, 11d))).expectNext(1L).expectComplete()
|
||||
.verify();
|
||||
StepVerifier.create(zSetOperations.range(key, new Range<>(0L, 5L))).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(value1);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void unionAndStore() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
K destKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, onlyInKey, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, shared, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(otherKey, onlyInOtherKey, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(otherKey, shared, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.unionAndStore(key, otherKey, destKey)).expectNext(3L).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.range(destKey, new Range<>(0L, 100L))).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(3);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void intersectAndStore() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
K destKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, onlyInKey, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, shared, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(otherKey, onlyInOtherKey, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(otherKey, shared, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.intersectAndStore(key, otherKey, destKey)).expectNext(1L).expectComplete()
|
||||
.verify();
|
||||
StepVerifier.create(zSetOperations.range(destKey, new Range<>(0L, 5L))).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1);
|
||||
}).verifyComplete();
|
||||
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rangeByLex() {
|
||||
|
||||
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V a = (V) "a";
|
||||
V b = (V) "b";
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, a, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, b, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.rangeByLex(key, new Range<>("a", "a"))).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(a);
|
||||
}).verifyComplete();
|
||||
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rangeByLexWithLimit() {
|
||||
|
||||
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V a = (V) "a";
|
||||
V b = (V) "b";
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, a, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, b, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.rangeByLex(key, new Range<>("a", "z"), Limit.limit().offset(0).count(10)))
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(2).contains(a, b);
|
||||
}).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.rangeByLex(key, new Range<>("a", "z"), Limit.limit().offset(1).count(10)))
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(b);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void reverseRangeByLex() {
|
||||
|
||||
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V a = (V) "a";
|
||||
V b = (V) "b";
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, a, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, b, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.reverseRangeByLex(key, new Range<>("a", "a"))).consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(a);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void reverseRangeByLexLimit() {
|
||||
|
||||
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V a = (V) "a";
|
||||
V b = (V) "b";
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, a, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, b, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.reverseRangeByLex(key, new Range<>("a", "z"), Limit.limit().offset(0).count(10)))
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(2).contains(b, a);
|
||||
}).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.reverseRangeByLex(key, new Range<>("a", "z"), Limit.limit().offset(1).count(10)))
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual).hasSize(1).contains(a);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void delete() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, value, 10)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.delete(key)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.size(key)).expectNext(0L).verifyComplete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.data.redis.ByteBufferObjectFactory;
|
||||
import org.springframework.data.redis.DoubleObjectFactory;
|
||||
import org.springframework.data.redis.LongObjectFactory;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.Person;
|
||||
import org.springframework.data.redis.PersonObjectFactory;
|
||||
import org.springframework.data.redis.PrefixStringObjectFactory;
|
||||
import org.springframework.data.redis.SettingsUtils;
|
||||
import org.springframework.data.redis.StringObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisClusterConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisClusterNode;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.GenericToStringSerializer;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.OxmSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.oxm.xstream.XStreamMarshaller;
|
||||
|
||||
/**
|
||||
* Parameters for testing implementations of {@link ReactiveRedisTemplate}
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
abstract public class ReactiveOperationsTestParams {
|
||||
|
||||
public static Collection<Object[]> testParams() {
|
||||
|
||||
ObjectFactory<String> stringFactory = new StringObjectFactory();
|
||||
ObjectFactory<String> clusterKeyStringFactory = new PrefixStringObjectFactory("{u1}.", stringFactory);
|
||||
ObjectFactory<Long> longFactory = new LongObjectFactory();
|
||||
ObjectFactory<Double> doubleFactory = new DoubleObjectFactory();
|
||||
ObjectFactory<ByteBuffer> rawFactory = new ByteBufferObjectFactory();
|
||||
ObjectFactory<Person> personFactory = new PersonObjectFactory();
|
||||
|
||||
// XStream serializer
|
||||
XStreamMarshaller xstream = new XStreamMarshaller();
|
||||
try {
|
||||
xstream.afterPropertiesSet();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Cannot init XStream", ex);
|
||||
}
|
||||
|
||||
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory();
|
||||
lettuceConnectionFactory.setPort(SettingsUtils.getPort());
|
||||
lettuceConnectionFactory.setHostName(SettingsUtils.getHost());
|
||||
lettuceConnectionFactory.afterPropertiesSet();
|
||||
|
||||
RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
|
||||
clusterConfiguration.addClusterNode(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_1_PORT));
|
||||
|
||||
LettuceConnectionFactory lettuceClusterConnectionFactory = new LettuceConnectionFactory(clusterConfiguration);
|
||||
lettuceClusterConnectionFactory.setPort(SettingsUtils.getPort());
|
||||
lettuceClusterConnectionFactory.setHostName(SettingsUtils.getHost());
|
||||
lettuceClusterConnectionFactory.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<Object, Object> objectTemplate = new ReactiveRedisTemplate<>();
|
||||
objectTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
objectTemplate.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<String, String> clusterStringTemplate = new ReactiveRedisTemplate<>();
|
||||
clusterStringTemplate.setConnectionFactory(lettuceClusterConnectionFactory);
|
||||
clusterStringTemplate.setDefaultSerializer(new StringRedisSerializer());
|
||||
clusterStringTemplate.setEnableDefaultSerializer(true);
|
||||
clusterStringTemplate.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<String, String> stringTemplate = new ReactiveRedisTemplate<>();
|
||||
stringTemplate.setDefaultSerializer(new StringRedisSerializer());
|
||||
stringTemplate.setEnableDefaultSerializer(true);
|
||||
stringTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
stringTemplate.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<String, Long> longTemplate = new ReactiveRedisTemplate<>();
|
||||
longTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
longTemplate.setValueSerializer(new GenericToStringSerializer<>(Long.class));
|
||||
longTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
longTemplate.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<String, Double> doubleTemplate = new ReactiveRedisTemplate<>();
|
||||
doubleTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
doubleTemplate.setValueSerializer(new GenericToStringSerializer<>(Double.class));
|
||||
doubleTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
doubleTemplate.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<byte[], byte[]> rawTemplate = new ReactiveRedisTemplate<>();
|
||||
rawTemplate.setEnableDefaultSerializer(false);
|
||||
rawTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
rawTemplate.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<String, Person> personTemplate = new ReactiveRedisTemplate<>();
|
||||
personTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
personTemplate.afterPropertiesSet();
|
||||
|
||||
OxmSerializer serializer = new OxmSerializer(xstream, xstream);
|
||||
ReactiveRedisTemplate<String, String> xstreamStringTemplate = new ReactiveRedisTemplate<>();
|
||||
xstreamStringTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
xstreamStringTemplate.setDefaultSerializer(serializer);
|
||||
xstreamStringTemplate.afterPropertiesSet();
|
||||
|
||||
ReactiveRedisTemplate<String, Person> xstreamPersonTemplate = new ReactiveRedisTemplate<>();
|
||||
xstreamPersonTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
xstreamPersonTemplate.setValueSerializer(serializer);
|
||||
xstreamPersonTemplate.afterPropertiesSet();
|
||||
|
||||
Jackson2JsonRedisSerializer<Person> jackson2JsonSerializer = new Jackson2JsonRedisSerializer<>(Person.class);
|
||||
ReactiveRedisTemplate<String, Person> jackson2JsonPersonTemplate = new ReactiveRedisTemplate<>();
|
||||
jackson2JsonPersonTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
jackson2JsonPersonTemplate.setValueSerializer(jackson2JsonSerializer);
|
||||
jackson2JsonPersonTemplate.afterPropertiesSet();
|
||||
|
||||
GenericJackson2JsonRedisSerializer genericJackson2JsonSerializer = new GenericJackson2JsonRedisSerializer();
|
||||
ReactiveRedisTemplate<String, Person> genericJackson2JsonPersonTemplate = new ReactiveRedisTemplate<>();
|
||||
genericJackson2JsonPersonTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
genericJackson2JsonPersonTemplate.setValueSerializer(genericJackson2JsonSerializer);
|
||||
genericJackson2JsonPersonTemplate.afterPropertiesSet();
|
||||
|
||||
return Arrays.asList(new Object[][] { //
|
||||
{ stringTemplate, stringFactory, stringFactory , "String"}, //
|
||||
{ clusterStringTemplate, clusterKeyStringFactory, stringFactory, "Cluster String" }, //
|
||||
{ objectTemplate, personFactory, personFactory , "Person/JDK"}, //
|
||||
{ longTemplate, stringFactory, longFactory , "Long"}, //
|
||||
{ doubleTemplate, stringFactory, doubleFactory , "Double"}, //
|
||||
{ rawTemplate, rawFactory, rawFactory , "raw"}, //
|
||||
{ personTemplate, stringFactory, personFactory , "String/Person/JDK"}, //
|
||||
{ xstreamStringTemplate, stringFactory, stringFactory , "String/OXM"}, //
|
||||
{ xstreamPersonTemplate, stringFactory, personFactory, "String/Person/OXM"}, //
|
||||
{ jackson2JsonPersonTemplate, stringFactory, personFactory, "Jackson2"}, //
|
||||
{ genericJackson2JsonPersonTemplate, stringFactory, personFactory, "Generic Jackson 2" } });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.Person;
|
||||
import org.springframework.data.redis.PersonObjectFactory;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisClusterConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.ReactiveSerializationContext;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link ReactiveRedisTemplate}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class ReactiveRedisTemplateIntegrationTests<K, V> {
|
||||
|
||||
private final ReactiveRedisTemplate<K, V> redisTemplate;
|
||||
|
||||
private final ObjectFactory<K> keyFactory;
|
||||
|
||||
private final ObjectFactory<V> valueFactory;
|
||||
|
||||
@Parameters(name = "{3}")
|
||||
public static Collection<Object[]> testParams() {
|
||||
return ReactiveOperationsTestParams.testParams();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
ConnectionFactoryTracker.cleanUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redisTemplate
|
||||
* @param keyFactory
|
||||
* @param valueFactory
|
||||
* @param label parameterized test label, no further use besides that.
|
||||
*/
|
||||
public ReactiveRedisTemplateIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate, ObjectFactory<K> keyFactory,
|
||||
ObjectFactory<V> valueFactory, String label) {
|
||||
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.keyFactory = keyFactory;
|
||||
this.valueFactory = valueFactory;
|
||||
|
||||
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
RedisConnectionFactory connectionFactory = (RedisConnectionFactory) redisTemplate.getConnectionFactory();
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
connection.flushAll();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void exists() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.hasKey(key)).expectNext(false).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(key, valueFactory.instance())).expectNext(true)
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.hasKey(key)).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void type() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.type(key)).expectNext(DataType.NONE).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(key, valueFactory.instance())).expectNext(true)
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.type(key)).expectNext(DataType.STRING).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void rename() {
|
||||
|
||||
K oldName = keyFactory.instance();
|
||||
K newName = keyFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(oldName, valueFactory.instance())).expectNext(true)
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.rename(oldName, newName)) //
|
||||
.expectNext(true) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void renameNx() {
|
||||
|
||||
K oldName = keyFactory.instance();
|
||||
K existing = keyFactory.instance();
|
||||
K newName = keyFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(oldName, valueFactory.instance())).expectNext(true)
|
||||
.verifyComplete();
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(existing, valueFactory.instance())).expectNext(true)
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.renameIfAbsent(oldName, newName)) //
|
||||
.expectNext(true) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(existing, valueFactory.instance())).expectNext(true)
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.renameIfAbsent(newName, existing)).expectNext(false) //
|
||||
.expectComplete() //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void expire() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.expire(key, Duration.ofSeconds(10))).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.getExpire(key)) //
|
||||
.consumeNextWith(actual -> assertThat(actual).isGreaterThan(Duration.ofSeconds(8))).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void preciseExpire() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.expire(key, Duration.ofMillis(10_001))).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.getExpire(key)) //
|
||||
.consumeNextWith(actual -> assertThat(actual).isGreaterThan(Duration.ofSeconds(8))).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void expireAt() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
Instant expireAt = Instant.ofEpochSecond(Instant.now().plus(Duration.ofSeconds(10)).getEpochSecond());
|
||||
|
||||
StepVerifier.create(redisTemplate.expireAt(key, expireAt)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.getExpire(key)) //
|
||||
.consumeNextWith(actual -> assertThat(actual).isGreaterThan(Duration.ofSeconds(8))) //
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void preciseExpireAt() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
Instant expireAt = Instant.ofEpochSecond(Instant.now().plus(Duration.ofSeconds(10)).getEpochSecond(), 5);
|
||||
|
||||
StepVerifier.create(redisTemplate.expireAt(key, expireAt)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.getExpire(key)) //
|
||||
.consumeNextWith(actual -> assertThat(actual).isGreaterThan(Duration.ofSeconds(8))) //
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void getTtlForAbsentKeyShouldCompleteWithoutValue() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.getExpire(key)).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void getTtlForKeyWithoutExpiryShouldCompleteWithZeroDuration() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.getExpire(key)).expectNext(Duration.ZERO).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void move() {
|
||||
|
||||
ReactiveRedisClusterConnection connection = null;
|
||||
try {
|
||||
connection = redisTemplate.getConnectionFactory().getReactiveClusterConnection();
|
||||
assumeTrue(connection == null);
|
||||
} catch (InvalidDataAccessApiUsageException e) {} finally {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(redisTemplate.opsForValue().set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.move(key, 5)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(redisTemplate.hasKey(key)).expectNext(false).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldApplyCustomSerializationContextToValues() {
|
||||
|
||||
Person key = new PersonObjectFactory().instance();
|
||||
Person value = new PersonObjectFactory().instance();
|
||||
|
||||
JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
|
||||
ReactiveSerializationContext<Object, Object> objectSerializers = ReactiveSerializationContext.builder()
|
||||
.key(jdkSerializer) //
|
||||
.value(jdkSerializer) //
|
||||
.hashKey(jdkSerializer) //
|
||||
.hashValue(jdkSerializer) //
|
||||
.build();
|
||||
|
||||
ReactiveValueOperations<Object, Object> valueOperations = redisTemplate.opsForValue(objectSerializers);
|
||||
|
||||
StepVerifier.create(valueOperations.set(key, value)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(valueOperations.get(key)).expectNext(value).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldApplyCustomSerializationContextToHash() {
|
||||
|
||||
ReactiveSerializationContext<K, V> serializationContext = redisTemplate.getSerializationContext();
|
||||
|
||||
K key = keyFactory.instance();
|
||||
String hashField = "foo";
|
||||
Person hashValue = new PersonObjectFactory().instance();
|
||||
|
||||
JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
|
||||
ReactiveSerializationContext<K, V> objectSerializers = ReactiveSerializationContext.<K, V> builder()
|
||||
.key(serializationContext.key()) //
|
||||
.value(serializationContext.value()) //
|
||||
.hashKey(new StringRedisSerializer()) //
|
||||
.hashValue(jdkSerializer) //
|
||||
.build();
|
||||
|
||||
ReactiveHashOperations<K, String, Object> hashOperations = redisTemplate.opsForHash(objectSerializers);
|
||||
|
||||
StepVerifier.create(hashOperations.put(key, hashField, hashValue)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(hashOperations.get(key, hashField)).expectNext(hashValue).verifyComplete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.serializer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ReactiveSerializationContext}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class ReactiveSerializationContextUnitTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) // DATAREDIS-602
|
||||
public void shouldRejectBuildIfKeySerializerIsNotSet() {
|
||||
|
||||
ReactiveSerializationContext.<String, String> builder() //
|
||||
.value(new StringRedisSerializer()) //
|
||||
.hashKey(new StringRedisSerializer()) //
|
||||
.hashValue(new StringRedisSerializer()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) // DATAREDIS-602
|
||||
public void shouldRejectBuildIfValueSerializerIsNotSet() {
|
||||
|
||||
ReactiveSerializationContext.<String, String> builder() //
|
||||
.key(new StringRedisSerializer()) //
|
||||
.hashKey(new StringRedisSerializer()) //
|
||||
.hashValue(new StringRedisSerializer()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) // DATAREDIS-602
|
||||
public void shouldRejectBuildIfHashKeySerializerIsNotSet() {
|
||||
|
||||
ReactiveSerializationContext.<String, String> builder() //
|
||||
.key(new StringRedisSerializer()) //
|
||||
.value(new StringRedisSerializer()) //
|
||||
.hashValue(new StringRedisSerializer()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) // DATAREDIS-602
|
||||
public void shouldRejectBuildIfHashValueSerializerIsNotSet() {
|
||||
|
||||
ReactiveSerializationContext.<String, String> builder() //
|
||||
.key(new StringRedisSerializer()) //
|
||||
.value(new StringRedisSerializer()) //
|
||||
.hashKey(new StringRedisSerializer()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldBuildSerializationContext() {
|
||||
|
||||
ReactiveSerializationContext<String, Long> serializationContext = createSerializationContext();
|
||||
|
||||
assertThat(serializationContext.key()).isNotNull();
|
||||
assertThat(serializationContext.value()).isNotNull();
|
||||
assertThat(serializationContext.hashKey()).isNotNull();
|
||||
assertThat(serializationContext.hashValue()).isNotNull();
|
||||
assertThat(serializationContext.string()).isNotNull();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldEncodeAndDecodeKey() {
|
||||
|
||||
ReactiveSerializationContext<String, Long> serializationContext = createSerializationContext();
|
||||
|
||||
String deserialized = serializationContext.key().read(serializationContext.key().write("foo"));
|
||||
|
||||
assertThat(deserialized).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void shouldEncodeAndDecodeValue() {
|
||||
|
||||
ReactiveSerializationContext<String, Long> serializationContext = createSerializationContext();
|
||||
|
||||
long deserialized = serializationContext.value().read(serializationContext.value().write(42L));
|
||||
|
||||
assertThat(deserialized).isEqualTo(42);
|
||||
}
|
||||
|
||||
private ReactiveSerializationContext<String, Long> createSerializationContext() {
|
||||
|
||||
return ReactiveSerializationContext.<String, Long> builder() //
|
||||
.key(new StringRedisSerializer()) //
|
||||
.value(ByteBuffer::getLong, value -> (ByteBuffer) ByteBuffer.allocate(8).putLong(value).flip()) //
|
||||
.hashKey(new StringRedisSerializer()) //
|
||||
.hashValue(new StringRedisSerializer()) //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user