Skip to content

Commit

Permalink
spring-projects#299 - Migrate Redis examples to Lettuce.
Browse files Browse the repository at this point in the history
We now use Lettuce API instead of Jedis to align with Boot's driver choice.
  • Loading branch information
mp911de committed Oct 10, 2017
1 parent ffc33fc commit 5760555
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 46 deletions.
6 changes: 3 additions & 3 deletions redis/repositories/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ redis/src $ ./redis-cli keys *

## Configuration ##

The below configuration uses [Jedis](https://github.com/xetorthio/jedis) to connect to Redis on its default port. Please note the usage of `@EnableRedisRepositories` to create `Repository` instances.
The below configuration uses [Lettuce](https://github.com/lettuce-io/lettuce-core) to connect to Redis on its default port. Please note the usage of `@EnableRedisRepositories` to create `Repository` instances.

```java
@Configuration
Expand All @@ -83,13 +83,13 @@ class AppConfig {

@Bean
RedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory();
return new LettuceConnectionFactory();
}

@Bean
RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory connectionFactory) {

RedisTemplate<byte[], byte[]> template = new RedisTemplate<byte[], byte[]>();
RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);

return template;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-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.
Expand All @@ -18,26 +18,27 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;

/**
* @author Christoph Strobl
* @author Mark Paluch
*/
@Configuration
@EnableRedisRepositories
public class ApplicationConfiguration {

@Bean
RedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory();
return new LettuceConnectionFactory();
}

@Bean
RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory connectionFactory) {

RedisTemplate<byte[], byte[]> template = new RedisTemplate<byte[], byte[]>();
RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);

return template;
Expand Down
2 changes: 1 addition & 1 deletion redis/sentinel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class RedisSentinelApplicationConfig {

@Bean
public RedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory(sentinelConfig());
return new LettuceConnectionFactory(sentinelConfig(), LettuceClientConfiguration.defaultConfiguration());
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StopWatch;

/**
* @author Christoph Strobl
* @author Oliver Gierke
* @author Mark Paluch
*/
@Configuration
public class RedisSentinelApplication {
Expand Down Expand Up @@ -74,7 +76,7 @@ public static void main(String[] args) throws Exception {
}

public @Bean RedisConnectionFactory connectionFactory() {
return new LettuceConnectionFactory(sentinelConfig());
return new LettuceConnectionFactory(sentinelConfig(), LettuceClientConfiguration.defaultConfiguration());
}

public @Bean RedisSentinelConfiguration sentinelConfig() {
Expand Down
4 changes: 2 additions & 2 deletions redis/util/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
</dependency>

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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 example.springdata.redis.test.util;

import io.lettuce.core.resource.ClientResources;
import io.lettuce.core.resource.DefaultClientResources;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
* Utility to keep track of a single {@link ClientResources} instance used from test rules to prevent costly
* creation/disposal of threading resources.
*
* @author Mark Paluch
*/
class ManagedClientResources {

private static final ManagedClientResources instance = new ManagedClientResources();

private final AtomicReference<ClientResources> clientResources = new AtomicReference<>();

/**
* Obtain a managed instance of {@link ClientResources}. Allocates an instance if {@link ManagedClientResources} was
* not initialized already.
*
* @return the {@link ClientResources}.
*/
static ClientResources getClientResources() {

AtomicReference<ClientResources> ref = instance.clientResources;

ClientResources clientResources = ref.get();
if (clientResources != null) {
return clientResources;
}

clientResources = DefaultClientResources.create();

if (ref.compareAndSet(null, clientResources)) {
return clientResources;
}

clientResources.shutdown(0, 0, TimeUnit.SECONDS);

return ref.get();
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-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.
Expand All @@ -15,17 +15,22 @@
*/
package example.springdata.redis.test.util;

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;

import java.time.Duration;

import org.junit.internal.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;

import redis.clients.jedis.Jedis;

/**
* @author Christoph Strobl
* @author Mark Paluch
*/
public class RequiresRedisSentinel implements TestRule {

Expand All @@ -44,8 +49,8 @@ protected RequiresRedisSentinel(RedisSentinelConfiguration config) {
}

/**
* Create new {@link RedisSentinelRule} for given {@link RedisSentinelConfiguration}.
*
* Create new {@link RequiresRedisSentinel} for given {@link RedisSentinelConfiguration}.
*
* @param config
* @return
*/
Expand All @@ -54,8 +59,8 @@ public static RequiresRedisSentinel forConfig(RedisSentinelConfiguration config)
}

/**
* Create new {@link RedisSentinelRule} using default configuration.
*
* Create new {@link RequiresRedisSentinel} using default configuration.
*
* @return
*/
public static RequiresRedisSentinel withDefaultConfig() {
Expand All @@ -70,7 +75,7 @@ public RequiresRedisSentinel sentinelsDisabled() {

/**
* Verifies all {@literal Sentinel} nodes are available.
*
*
* @return
*/
public RequiresRedisSentinel allActive() {
Expand All @@ -81,7 +86,7 @@ public RequiresRedisSentinel allActive() {

/**
* Verifies at least one {@literal Sentinel} node is available.
*
*
* @return
*/
public RequiresRedisSentinel oneActive() {
Expand All @@ -93,7 +98,7 @@ public RequiresRedisSentinel oneActive() {
/**
* Will only check {@link RedisSentinelConfiguration} configuration in case {@link RequiresRedisSentinel} is detected
* on test method.
*
*
* @return
*/
public RequiresRedisSentinel dynamicModeSelection() {
Expand Down Expand Up @@ -138,9 +143,9 @@ private void verify(SentinelsAvailable verificationMode) {

if (failed > 0) {
if (SentinelsAvailable.ALL_ACTIVE.equals(verificationMode)) {
throw new AssumptionViolatedException(String.format(
"Expected all Redis Sentinels to respone but %s of %s did not responde", failed, sentinelConfig
.getSentinels().size()));
throw new AssumptionViolatedException(
String.format("Expected all Redis Sentinels to respone but %s of %s did not responde", failed,
sentinelConfig.getSentinels().size()));
}

if (SentinelsAvailable.ONE_ACTIVE.equals(verificationMode) && sentinelConfig.getSentinels().size() - 1 < failed) {
Expand All @@ -150,32 +155,23 @@ private void verify(SentinelsAvailable verificationMode) {
}

if (SentinelsAvailable.NONE_ACTIVE.equals(verificationMode) && failed != sentinelConfig.getSentinels().size()) {
throw new AssumptionViolatedException(String.format(
"Expected to have no sentinels online but found that %s are still alive.", (sentinelConfig.getSentinels()
.size() - failed)));
throw new AssumptionViolatedException(
String.format("Expected to have no sentinels online but found that %s are still alive.",
(sentinelConfig.getSentinels().size() - failed)));
}
}

private boolean isAvailable(RedisNode node) {

Jedis jedis = null;
RedisClient redisClient = RedisClient.create(ManagedClientResources.getClientResources(),
RedisURI.create(node.getHost(), node.getPort()));

try {
jedis = new Jedis(node.getHost(), node.getPort());
jedis.connect();
jedis.ping();
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
connection.sync().ping();
} catch (Exception e) {
return false;
} finally {

if (jedis != null) {
try {
jedis.disconnect();
jedis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
redisClient.shutdown(Duration.ZERO, Duration.ZERO);
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
*/
package example.springdata.redis.test.util;

import redis.clients.jedis.Jedis;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;

import java.net.InetSocketAddress;
import java.net.Socket;
import java.time.Duration;

import org.junit.AssumptionViolatedException;
import org.junit.rules.ExternalResource;
import org.springframework.data.redis.connection.jedis.JedisConverters;
import org.springframework.data.redis.connection.lettuce.LettuceConverters;
import org.springframework.data.util.Version;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
Expand Down Expand Up @@ -107,16 +110,22 @@ protected void before() throws Throwable {
return;
}

try (Jedis jedis = new Jedis(host, port)) {
RedisClient redisClient = RedisClient.create(ManagedClientResources.getClientResources(),
RedisURI.create(host, port));

String infoServer = jedis.info("server");
String redisVersion = JedisConverters.stringToProps().convert(infoServer).getProperty("redis_version");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {

String infoServer = connection.sync().info("server");
String redisVersion = LettuceConverters.stringToProps().convert(infoServer).getProperty("redis_version");
Version runningVersion = Version.parse(redisVersion);

if (runningVersion.isLessThan(requiredVersion)) {
throw new AssumptionViolatedException(String
.format("This test requires Redis version %s but you run version %s", requiredVersion, runningVersion));
}

} finally {
redisClient.shutdown(Duration.ZERO, Duration.ZERO);
}
}
}

0 comments on commit 5760555

Please sign in to comment.