Skip to content

Commit d078a63

Browse files
christophstroblodrotbohm
authored andcommitted
DATAREDIS-431 - Autoselect database configured in LettuceConnectionFactory.
We now actively select the predefined db set via the dbIndex on LettuceConnectionFactory. Fixed some spelling issues along the way. Original pull request: #157.
1 parent 3d7a524 commit d078a63

File tree

10 files changed

+113
-19
lines changed

10 files changed

+113
-19
lines changed

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ public class LettuceConnection extends AbstractRedisConnection {
127127
LettuceConverters.exceptionConverter());
128128
private static final TypeHints typeHints = new TypeHints();
129129

130+
private final int defaultDbIndex;
131+
private int dbIndex;
132+
130133
static {
131134
SYNC_HANDLER = ReflectionUtils.findMethod(AbstractRedisClient.class, "syncHandler", RedisChannelHandler.class,
132135
Class[].class);
@@ -293,11 +296,29 @@ public LettuceConnection(com.lambdaworks.redis.RedisAsyncConnection<byte[], byte
293296
*/
294297
public LettuceConnection(com.lambdaworks.redis.RedisAsyncConnection<byte[], byte[]> sharedConnection, long timeout,
295298
RedisClient client, LettucePool pool) {
299+
300+
this(sharedConnection, timeout, client, pool, 0);
301+
}
302+
303+
/**
304+
* @param sharedConnection A native connection that is shared with other {@link LettuceConnection}s. Should not be
305+
* used for transactions or blocking operations
306+
* @param timeout The connection timeout (in milliseconds)
307+
* @param client The {@link RedisClient} to use when making pub/sub connections.
308+
* @param pool The connection pool to use for blocking and tx operations.
309+
* @param defaultDbIndex The db index to use along with {@link RedisClient} when establishing a dedicated connection.
310+
* @since 1.7
311+
*/
312+
public LettuceConnection(com.lambdaworks.redis.RedisAsyncConnection<byte[], byte[]> sharedConnection, long timeout,
313+
RedisClient client, LettucePool pool, int defaultDbIndex) {
314+
296315
this.asyncSharedConn = sharedConnection;
297316
this.timeout = timeout;
298317
this.client = client;
299318
this.sharedConn = sharedConnection != null ? syncConnection(asyncSharedConn) : null;
300319
this.pool = pool;
320+
this.defaultDbIndex = defaultDbIndex;
321+
this.dbIndex = this.defaultDbIndex;
301322
}
302323

303324
protected DataAccessException convertLettuceAccessException(Exception ex) {
@@ -404,6 +425,8 @@ public void close() throws DataAccessException {
404425
}
405426
subscription = null;
406427
}
428+
429+
this.dbIndex = defaultDbIndex;
407430
}
408431

409432
public boolean isClosed() {
@@ -1075,6 +1098,7 @@ public Boolean renameNX(byte[] oldName, byte[] newName) {
10751098
}
10761099

10771100
public void select(int dbIndex) {
1101+
10781102
if (asyncSharedConn != null) {
10791103
throw new UnsupportedOperationException("Selecting a new database not supported due to shared connection. "
10801104
+ "Use separate ConnectionFactorys to work with multiple databases");
@@ -1083,6 +1107,8 @@ public void select(int dbIndex) {
10831107
throw new UnsupportedOperationException("Lettuce blocks for #select");
10841108
}
10851109
try {
1110+
1111+
this.dbIndex = dbIndex;
10861112
if (isQueueing()) {
10871113
transaction(new LettuceTxStatusResult(getConnection().select(dbIndex)));
10881114
return;
@@ -3412,7 +3438,9 @@ private RedisAsyncConnection<byte[], byte[]> getAsyncDedicatedConnection() {
34123438
if (this.pool != null) {
34133439
this.asyncDedicatedConn = pool.getResource();
34143440
} else {
3441+
34153442
this.asyncDedicatedConn = client.connectAsync(CODEC);
3443+
this.asyncDedicatedConn.select(dbIndex);
34163444
}
34173445
}
34183446
return asyncDedicatedConn;

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,13 @@ public void destroy() {
118118
client.shutdown(shutdownTimeout, shutdownTimeout, TimeUnit.MILLISECONDS);
119119
}
120120

121+
/*
122+
* (non-Javadoc)
123+
* @see org.springframework.data.redis.connection.RedisConnectionFactory#getConnection()
124+
*/
121125
public RedisConnection getConnection() {
122-
LettuceConnection connection = new LettuceConnection(getSharedConnection(), timeout, client, pool);
126+
127+
LettuceConnection connection = new LettuceConnection(getSharedConnection(), timeout, client, pool, dbIndex);
123128
connection.setConvertPipelineAndTxResults(convertPipelineAndTxResults);
124129
return connection;
125130
}

src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ public void setUp() {
111111
@After
112112
public void tearDown() {
113113
try {
114-
connection.flushDb();
114+
115+
// since we use more than one db we're required to flush them all
116+
connection.flushAll();
115117
} catch (Exception e) {
116118
// Connection may be closed in certain cases, like after pub/sub
117119
// tests

src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionIntegrationTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2014 the original author or authors.
2+
* Copyright 2011-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,7 +72,7 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati
7272
@After
7373
public void tearDown() {
7474
try {
75-
connection.flushDb();
75+
connection.flushAll();
7676
} catch (Exception e) {
7777
// Jedis leaves some incomplete data in OutputStream on NPE caused
7878
// by null key/value tests

src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP
4949
@After
5050
public void tearDown() {
5151
try {
52-
connection.flushDb();
52+
connection.flushAll();
5353
connection.close();
5454
} catch (Exception e) {
5555
// Jedis leaves some incomplete data in OutputStream on NPE caused
@@ -135,7 +135,7 @@ public void testScriptLoadEvalSha() {
135135
public void testEvalShaArrayStrings() {
136136
super.testEvalShaArrayStrings();
137137
}
138-
138+
139139
@Test(expected = UnsupportedOperationException.class)
140140
@IfProfileValue(name = "redisVersion", value = "2.6+")
141141
public void testEvalShaArrayBytes() {

src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionTransactionIntegrationTests.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import org.junit.Ignore;
2020
import org.junit.Test;
2121
import org.junit.runner.RunWith;
22-
2322
import org.springframework.dao.InvalidDataAccessApiUsageException;
2423
import org.springframework.data.redis.connection.AbstractConnectionTransactionIntegrationTests;
2524
import org.springframework.data.redis.test.util.RelaxedJUnit4ClassRunner;
@@ -41,7 +40,7 @@ public class JedisConnectionTransactionIntegrationTests extends AbstractConnecti
4140
@After
4241
public void tearDown() {
4342
try {
44-
connection.flushDb();
43+
connection.flushAll();
4544
connection.close();
4645
} catch (Exception e) {
4746
// Jedis leaves some incomplete data in OutputStream on NPE caused
@@ -67,7 +66,7 @@ public void testScriptLoadEvalSha() {
6766
public void testEvalShaArrayStrings() {
6867
super.testEvalShaArrayStrings();
6968
}
70-
69+
7170
@Test(expected = UnsupportedOperationException.class)
7271
@IfProfileValue(name = "redisVersion", value = "2.6+")
7372
public void testEvalShaArrayBytes() {

src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionIntegrationTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2014 the original author or authors.
2+
* Copyright 2011-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
6060
@After
6161
public void tearDown() {
6262
try {
63-
connection.flushDb();
63+
connection.flushAll();
6464
connection.close();
6565
} catch (DataAccessException e) {
6666
// Jredis closes a connection on Exception (which some tests
@@ -435,7 +435,7 @@ public void testScriptLoadEvalSha() {
435435
public void testEvalShaArrayStrings() {
436436
super.testEvalShaArrayStrings();
437437
}
438-
438+
439439
@Test(expected = UnsupportedOperationException.class)
440440
@IfProfileValue(name = "redisVersion", value = "2.6+")
441441
public void testEvalShaArrayBytes() {

src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryTests.java

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2013 the original author or authors.
2+
* Copyright 2011-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,26 +15,31 @@
1515
*/
1616
package org.springframework.data.redis.connection.lettuce;
1717

18-
import com.lambdaworks.redis.RedisAsyncConnection;
19-
import com.lambdaworks.redis.RedisException;
18+
import static org.hamcrest.core.IsNull.*;
19+
import static org.junit.Assert.*;
20+
2021
import org.junit.After;
22+
import org.junit.AfterClass;
2123
import org.junit.Before;
2224
import org.junit.Ignore;
2325
import org.junit.Test;
26+
import org.springframework.data.redis.ConnectionFactoryTracker;
2427
import org.springframework.data.redis.RedisConnectionFailureException;
2528
import org.springframework.data.redis.RedisSystemException;
2629
import org.springframework.data.redis.SettingsUtils;
2730
import org.springframework.data.redis.connection.DefaultStringRedisConnection;
2831
import org.springframework.data.redis.connection.RedisConnection;
2932
import org.springframework.data.redis.connection.StringRedisConnection;
3033

31-
import static org.junit.Assert.*;
34+
import com.lambdaworks.redis.RedisAsyncConnection;
35+
import com.lambdaworks.redis.RedisException;
3236

3337
/**
3438
* Integration test of {@link LettuceConnectionFactory}
3539
*
3640
* @author Jennifer Hickey
3741
* @author Thomas Darimont
42+
* @author Christoph Strobl
3843
*/
3944
public class LettuceConnectionFactoryTests {
4045

@@ -44,6 +49,7 @@ public class LettuceConnectionFactoryTests {
4449

4550
@Before
4651
public void setUp() {
52+
4753
factory = new LettuceConnectionFactory(SettingsUtils.getHost(), SettingsUtils.getPort());
4854
factory.afterPropertiesSet();
4955
factory.setShutdownTimeout(0);
@@ -59,6 +65,11 @@ public void tearDown() {
5965
}
6066
}
6167

68+
@AfterClass
69+
public static void cleanUp() {
70+
ConnectionFactoryTracker.cleanUp();
71+
}
72+
6273
@SuppressWarnings("rawtypes")
6374
@Test
6475
public void testGetNewConnectionOnError() throws Exception {
@@ -109,10 +120,14 @@ public void testValidateNoError() {
109120

110121
@Test
111122
public void testSelectDb() {
123+
112124
LettuceConnectionFactory factory2 = new LettuceConnectionFactory(SettingsUtils.getHost(), SettingsUtils.getPort());
113125
factory2.setShutdownTimeout(0);
114126
factory2.setDatabase(1);
115127
factory2.afterPropertiesSet();
128+
129+
ConnectionFactoryTracker.add(factory2);
130+
116131
StringRedisConnection connection2 = new DefaultStringRedisConnection(factory2.getConnection());
117132
connection2.flushDb();
118133
// put an item in database 0
@@ -213,6 +228,9 @@ public void testCreateFactoryWithPool() {
213228
LettuceConnectionFactory factory2 = new LettuceConnectionFactory(pool);
214229
factory2.setShutdownTimeout(0);
215230
factory2.afterPropertiesSet();
231+
232+
ConnectionFactoryTracker.add(factory2);
233+
216234
RedisConnection conn2 = factory2.getConnection();
217235
conn2.close();
218236
factory2.destroy();
@@ -228,6 +246,9 @@ public void testLotsOfConnections() throws InterruptedException {
228246
pool.afterPropertiesSet();
229247
final LettuceConnectionFactory factory2 = new LettuceConnectionFactory(pool);
230248
factory2.afterPropertiesSet();
249+
250+
ConnectionFactoryTracker.add(factory2);
251+
231252
for (int i = 1; i < 1000; i++) {
232253
Thread th = new Thread(new Runnable() {
233254
public void run() {
@@ -250,4 +271,30 @@ public void testConnectWithPassword() {
250271
conn.bLPop(1, "key".getBytes());
251272
conn.close();
252273
}
274+
275+
/**
276+
* @see DATAREDIS-431
277+
*/
278+
@Test
279+
public void dbIndexShouldBePropagatedCorrectly() {
280+
281+
LettuceConnectionFactory factory = new LettuceConnectionFactory();
282+
factory.setDatabase(2);
283+
factory.afterPropertiesSet();
284+
285+
ConnectionFactoryTracker.add(factory);
286+
287+
StringRedisConnection connectionToDbIndex2 = new DefaultStringRedisConnection(factory.getConnection());
288+
289+
try {
290+
291+
String key = "key-in-db-2";
292+
connectionToDbIndex2.set(key, "the wheel of time");
293+
294+
assertThat(connection.get(key), nullValue());
295+
assertThat(connectionToDbIndex2.get(key), notNullValue());
296+
} finally {
297+
connectionToDbIndex2.close();
298+
}
299+
}
253300
}

src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionUnitTestSuite.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ public class LettuceConnectionUnitTestSuite {
4646
public static class LettuceConnectionUnitTests extends AbstractConnectionUnitTestBase<RedisAsyncConnectionImpl> {
4747

4848
protected LettuceConnection connection;
49+
private RedisClient clientMock;
4950

5051
@SuppressWarnings({ "unchecked" })
5152
@Before
5253
public void setUp() throws InvocationTargetException, IllegalAccessException {
5354

54-
RedisClient clientMock = mock(RedisClient.class);
55+
clientMock = mock(RedisClient.class);
5556
when(clientMock.connectAsync((RedisCodec) any())).thenReturn(getNativeRedisConnectionMock());
5657
connection = new LettuceConnection(0, clientMock);
5758
}
@@ -142,6 +143,18 @@ public void slaveOfNoOneShouldBeSentCorrectly() {
142143
public void shouldThrowExceptionWhenAccessingRedisSentinelsCommandsWhenNoSentinelsConfigured() {
143144
connection.getSentinelConnection();
144145
}
146+
147+
/**
148+
* @see DATAREDIS-431
149+
*/
150+
@Test
151+
public void dbIndexShouldBeSetWhenOptainingConnection() {
152+
153+
connection = new LettuceConnection(null, 0, clientMock, null, 1);
154+
connection.getNativeConnection();
155+
156+
verify(getNativeRedisConnectionMock(), times(1)).select(1);
157+
}
145158
}
146159

147160
public static class LettucePipelineConnectionUnitTests extends LettuceConnectionUnitTests {

src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionIntegrationTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2014 the original author or authors.
2+
* Copyright 2011-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ public class SrpConnectionIntegrationTests extends AbstractConnectionIntegration
5151
@After
5252
public void tearDown() {
5353
try {
54-
connection.flushDb();
54+
connection.flushAll();
5555
} catch (Exception e) {
5656
// SRP doesn't allow other commands to be executed once subscribed,
5757
// so

0 commit comments

Comments
 (0)