Add authentication to Lettuce conn factory and pool
DATAREDIS-202
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import com.lambdaworks.redis.RedisAsyncConnection;
|
||||
import com.lambdaworks.redis.RedisClient;
|
||||
import com.lambdaworks.redis.RedisConnection;
|
||||
import com.lambdaworks.redis.codec.RedisCodec;
|
||||
import com.lambdaworks.redis.pubsub.RedisPubSubConnection;
|
||||
|
||||
/**
|
||||
* Extension of {@link RedisClient} that calls auth on all new connections using
|
||||
* the supplied credentials
|
||||
*
|
||||
* @author Jennifer Hickey
|
||||
*
|
||||
*/
|
||||
public class AuthenticatingRedisClient extends RedisClient {
|
||||
|
||||
private String password;
|
||||
|
||||
public AuthenticatingRedisClient(String host, int port, String password) {
|
||||
super(host, port);
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public AuthenticatingRedisClient(String host, String password) {
|
||||
super(host);
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> RedisConnection<K, V> connect(RedisCodec<K, V> codec) {
|
||||
RedisConnection<K, V> conn = super.connect(codec);
|
||||
conn.auth(password);
|
||||
return conn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> RedisAsyncConnection<K, V> connectAsync(RedisCodec<K, V> codec) {
|
||||
RedisAsyncConnection<K, V> conn = super.connectAsync(codec);
|
||||
conn.auth(password);
|
||||
return conn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> RedisPubSubConnection<K, V> connectPubSub(RedisCodec<K, V> codec) {
|
||||
RedisPubSubConnection<K, V> conn = super.connectPubSub(codec);
|
||||
conn.auth(password);
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,9 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.apache.commons.pool.BasePoolableObjectFactory;
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
import org.apache.commons.pool.impl.GenericObjectPool.Config;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.redis.connection.PoolException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.lambdaworks.redis.RedisAsyncConnection;
|
||||
import com.lambdaworks.redis.RedisClient;
|
||||
@@ -31,10 +33,22 @@ import com.lambdaworks.redis.RedisClient;
|
||||
* @author Jennifer Hickey
|
||||
*
|
||||
*/
|
||||
public class DefaultLettucePool implements LettucePool {
|
||||
private final GenericObjectPool internalPool;
|
||||
private static final int DEFAULT_TIMEOUT = (int) TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS);
|
||||
public class DefaultLettucePool implements LettucePool, InitializingBean {
|
||||
private GenericObjectPool internalPool;
|
||||
private RedisClient client;
|
||||
private int dbIndex = 0;
|
||||
private Config poolConfig = new Config();
|
||||
private String hostName = "localhost";
|
||||
private int port = 6379;
|
||||
private String password;
|
||||
private long timeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS);
|
||||
|
||||
/**
|
||||
* Constructs a new <code>DefaultLettucePool</code> instance with
|
||||
* default settings.
|
||||
*/
|
||||
public DefaultLettucePool() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the {@link Config} and {@link RedisClient} defaults for configuring
|
||||
@@ -46,7 +60,8 @@ public class DefaultLettucePool implements LettucePool {
|
||||
* The Redis port
|
||||
*/
|
||||
public DefaultLettucePool(String hostName, int port) {
|
||||
this(hostName, port, 0, DEFAULT_TIMEOUT, new Config());
|
||||
this.hostName = hostName;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,84 +75,17 @@ public class DefaultLettucePool implements LettucePool {
|
||||
* The pool {@link Config}
|
||||
*/
|
||||
public DefaultLettucePool(String hostName, int port, Config poolConfig) {
|
||||
this(hostName, port, 0, DEFAULT_TIMEOUT, poolConfig);
|
||||
this.hostName = hostName;
|
||||
this.port = port;
|
||||
this.poolConfig = poolConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Uses the {@link Config} defaults for configuring the connection pool
|
||||
*
|
||||
* @param client
|
||||
* The {@link RedisClient} for connecting to Redis
|
||||
*
|
||||
*/
|
||||
public DefaultLettucePool(RedisClient client) {
|
||||
this.client = client;
|
||||
this.internalPool = new GenericObjectPool(new LettuceFactory(client, 0), new Config());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param client
|
||||
* The {@link RedisClient} for connecting to Redis
|
||||
*
|
||||
* @param poolConfig
|
||||
* The pool {@link Config}
|
||||
* @param dbIndex
|
||||
* The index of the database all connections should use. The
|
||||
* database will be selected when connections are activated.
|
||||
*/
|
||||
public DefaultLettucePool(RedisClient client, Config poolConfig, int dbIndex) {
|
||||
this.client = client;
|
||||
this.internalPool = new GenericObjectPool(new LettuceFactory(client, dbIndex), poolConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the {@link Config} defaults for configuring the connection pool
|
||||
*
|
||||
* @param hostName
|
||||
* The Redis host
|
||||
* @param port
|
||||
* The Redis port
|
||||
* @param dbIndex
|
||||
* The index of the database all connections should use. The
|
||||
* database will be selected when connections are activated.
|
||||
* @param password
|
||||
* The password used for authenticating with the Redis server or
|
||||
* null if no password required
|
||||
* @param timeout
|
||||
* The socket timeout or 0 to use the default socket timeout
|
||||
*/
|
||||
public DefaultLettucePool(String hostName, int port, int dbIndex, int timeout) {
|
||||
this(hostName, port, dbIndex, timeout, new Config());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param hostName
|
||||
* The Redis host
|
||||
* @param port
|
||||
* The Redis port
|
||||
* @param dbIndex
|
||||
* The index of the database all connections should use. The
|
||||
* database will be selected when connections are activated.
|
||||
* @param password
|
||||
* The password used for authenticating with the Redis server or
|
||||
* null if no password required
|
||||
* @param timeout
|
||||
* The socket timeout or 0 to use the default socket timeout
|
||||
* @param poolConfig
|
||||
* The pool {@link COnfig}
|
||||
*/
|
||||
public DefaultLettucePool(String hostName, int port, int dbIndex, int timeout, Config poolConfig) {
|
||||
this.client = new RedisClient(hostName, port);
|
||||
public void afterPropertiesSet() {
|
||||
this.client = password != null ? new AuthenticatingRedisClient(hostName, port, password) :
|
||||
new RedisClient(hostName, port);
|
||||
client.setDefaultTimeout(timeout, TimeUnit.MILLISECONDS);
|
||||
this.internalPool = new GenericObjectPool(new LettuceFactory(client, dbIndex), poolConfig);
|
||||
}
|
||||
|
||||
public RedisClient getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public RedisAsyncConnection<byte[], byte[]> getResource() {
|
||||
@@ -172,6 +120,122 @@ public class DefaultLettucePool implements LettucePool {
|
||||
}
|
||||
}
|
||||
|
||||
public RedisClient getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The pool configuration
|
||||
*/
|
||||
public Config getPoolConfig() {
|
||||
return poolConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param poolConfig The pool configuration to use
|
||||
*/
|
||||
public void setPoolConfig(Config poolConfig) {
|
||||
this.poolConfig = poolConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the database.
|
||||
*
|
||||
* @return Returns the database index
|
||||
*/
|
||||
public int getDatabase() {
|
||||
return dbIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the index of the database used by this connection pool. Default
|
||||
* is 0.
|
||||
*
|
||||
* @param index
|
||||
* database index
|
||||
*/
|
||||
public void setDatabase(int index) {
|
||||
Assert.isTrue(index >= 0, "invalid DB index (a positive index required)");
|
||||
this.dbIndex = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password used for authenticating with the Redis server.
|
||||
*
|
||||
* @return password for authentication
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password used for authenticating with the Redis server.
|
||||
*
|
||||
* @param password the password to set
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current host.
|
||||
*
|
||||
* @return the host
|
||||
*/
|
||||
public String getHostName() {
|
||||
return hostName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the host.
|
||||
*
|
||||
* @param host
|
||||
* the host to set
|
||||
*/
|
||||
public void setHostName(String host) {
|
||||
this.hostName = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current port.
|
||||
*
|
||||
* @return the port
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the port.
|
||||
*
|
||||
* @param port
|
||||
* the port to set
|
||||
*/
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the connection timeout (in milliseconds).
|
||||
*
|
||||
* @return connection timeout
|
||||
*/
|
||||
public long getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the connection timeout (in milliseconds).
|
||||
*
|
||||
* @param timeout
|
||||
* connection timeout
|
||||
*/
|
||||
public void setTimeout(long timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
private static class LettuceFactory extends BasePoolableObjectFactory {
|
||||
|
||||
private final RedisClient client;
|
||||
|
||||
@@ -70,6 +70,7 @@ public class LettuceConnectionFactory implements InitializingBean, DisposableBea
|
||||
private int dbIndex = 0;
|
||||
/** Synchronization monitor for the shared Connection */
|
||||
private final Object connectionMonitor = new Object();
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>LettuceConnectionFactory</code> instance with
|
||||
@@ -278,6 +279,24 @@ public class LettuceConnectionFactory implements InitializingBean, DisposableBea
|
||||
this.dbIndex = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password used for authenticating with the Redis server.
|
||||
*
|
||||
* @return password for authentication
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password used for authenticating with the Redis server.
|
||||
*
|
||||
* @param password the password to set
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
protected RedisAsyncConnection<byte[], byte[]> getSharedConnection() {
|
||||
if (shareNativeConnection) {
|
||||
synchronized (this.connectionMonitor) {
|
||||
@@ -314,7 +333,8 @@ public class LettuceConnectionFactory implements InitializingBean, DisposableBea
|
||||
if(pool != null) {
|
||||
return pool.getClient();
|
||||
}
|
||||
RedisClient client = new RedisClient(hostName, port);
|
||||
RedisClient client = password != null ? new AuthenticatingRedisClient(hostName, port, password) :
|
||||
new RedisClient(hostName, port);
|
||||
client.setDefaultTimeout(timeout, TimeUnit.MILLISECONDS);
|
||||
return client;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user