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:
Mark Paluch
2017-02-09 17:59:31 +01:00
committed by Christoph Strobl
parent bf1a7ac8a3
commit 81657c530b
55 changed files with 10172 additions and 158 deletions

View File

@@ -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());
}
}

View File

@@ -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);
}

View File

@@ -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());
}
}

View File

@@ -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));
}
}

View File

@@ -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())));
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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" } });
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}