+ connection implementations mainly finished
+ aggregated cached vs non-cached jedis strategies + added more exception translations
This commit is contained in:
@@ -1,35 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
/**
|
||||
* Fatal exception thrown when we can't connect to Redis.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
public class CannotGetRedisConnectionException extends DataAccessResourceFailureException {
|
||||
|
||||
public CannotGetRedisConnectionException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CannotGetRedisConnectionException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
/**
|
||||
* Fatal exception thrown when the Redis connection fails completely.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
public class RedisConnectionFailureException extends DataAccessResourceFailureException {
|
||||
|
||||
public RedisConnectionFailureException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public RedisConnectionFailureException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis.core.connection;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Enumeration of the Redis data types.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public enum DataType {
|
||||
|
||||
NONE("none"), STRING("string"), LIST("list"), SET("set"), ZSET("zset"), HASH("hash");
|
||||
|
||||
private static final Map<String, DataType> codeLookup = new ConcurrentHashMap<String, DataType>(6);
|
||||
|
||||
static {
|
||||
for (DataType type : EnumSet.allOf(DataType.class))
|
||||
codeLookup.put(type.code, type);
|
||||
|
||||
}
|
||||
|
||||
private final String code;
|
||||
|
||||
DataType(String name) {
|
||||
this.code = name;
|
||||
}
|
||||
|
||||
public String code() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static DataType fromCode(String code) {
|
||||
DataType data = codeLookup.get(code);
|
||||
if (data == null)
|
||||
throw new IllegalArgumentException("unknown data type code");
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public interface RedisCommands {
|
||||
|
||||
int del(String... keys);
|
||||
|
||||
DataTypes type(String key);
|
||||
DataType type(String key);
|
||||
|
||||
Collection<String> keys(String pattern);
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ import org.springframework.datastore.redis.UncategorizedRedisException;
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public interface RedisConnection extends RedisCommands {
|
||||
public interface RedisConnection<T> extends RedisCommands, RedisHashCommands, RedisListCommands, RedisSetCommands,
|
||||
RedisStringCommands, RedisZSetCommands {
|
||||
|
||||
/**
|
||||
* Close (or quit) the connection.
|
||||
@@ -35,5 +36,7 @@ public interface RedisConnection extends RedisCommands {
|
||||
|
||||
boolean isClosed();
|
||||
|
||||
<T> T getNativeConnection();
|
||||
T getNativeConnection();
|
||||
|
||||
String getCharset();
|
||||
}
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
package org.springframework.datastore.redis.core.connection;
|
||||
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
|
||||
/**
|
||||
* Enumeration of the Redis data types.
|
||||
* Thread-safe factory of Redis connections. Additionally performs exception translation
|
||||
* between the underlying Redis client library and Spring DAO exceptions.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public enum DataTypes {
|
||||
public interface RedisConnectionFactory extends PersistenceExceptionTranslator {
|
||||
|
||||
NONE, STRING, LIST, SET, ZSET, HASH;
|
||||
RedisConnection<?> getConnection();
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.springframework.datastore.redis.core.connection;
|
||||
|
||||
/**
|
||||
* String specific commands supported by Redis .
|
||||
* String specific commands supported by Redis.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis.core.connection.jedis;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.datastore.keyvalue.UncategorizedKeyvalueStoreException;
|
||||
import org.springframework.datastore.redis.UncategorizedRedisException;
|
||||
import org.springframework.datastore.redis.core.connection.DataType;
|
||||
import org.springframework.datastore.redis.core.connection.RedisConnection;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import redis.clients.jedis.Client;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisException;
|
||||
|
||||
/**
|
||||
* Jedis based {@link RedisConnection}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class JedisConnection implements RedisConnection<Jedis> {
|
||||
|
||||
private static final Field CLIENT_FIELD;
|
||||
|
||||
static {
|
||||
CLIENT_FIELD = ReflectionUtils.findField(Jedis.class, "client", Client.class);
|
||||
ReflectionUtils.makeAccessible(CLIENT_FIELD);
|
||||
}
|
||||
|
||||
private final Jedis jedis;
|
||||
private final Client client;
|
||||
|
||||
public JedisConnection(Jedis jedis) {
|
||||
this.jedis = jedis;
|
||||
// extract underlying client for batch operations
|
||||
client = (Client) ReflectionUtils.getField(CLIENT_FIELD, jedis);
|
||||
}
|
||||
|
||||
protected DataAccessException convertJedisAccessException(Exception ex) {
|
||||
if (ex instanceof JedisException) {
|
||||
return JedisUtils.convertJedisAccessException((JedisException) ex);
|
||||
}
|
||||
if (ex instanceof IOException) {
|
||||
return JedisUtils.convertJedisAccessException((IOException) ex);
|
||||
}
|
||||
|
||||
throw new UncategorizedKeyvalueStoreException("Unknown jedis exception", ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws UncategorizedRedisException {
|
||||
try {
|
||||
jedis.disconnect();
|
||||
jedis.quit();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharset() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jedis getNativeConnection() {
|
||||
return jedis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
try {
|
||||
return !jedis.isConnected();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int dbSize() {
|
||||
try {
|
||||
return jedis.dbSize();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int del(String... keys) {
|
||||
try {
|
||||
return jedis.del(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void discard() {
|
||||
try {
|
||||
client.discard();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exec() {
|
||||
try {
|
||||
client.exec();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(String key) {
|
||||
try {
|
||||
return (jedis.exists(key) == 1);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean expire(String key, long seconds) {
|
||||
try {
|
||||
return (jedis.expire(key, (int) seconds) == 1);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> keys(String pattern) {
|
||||
try {
|
||||
return (jedis.keys(pattern));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void multi() {
|
||||
try {
|
||||
jedis.multi();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist(String key) {
|
||||
try {
|
||||
return (jedis.persist(key) == 1);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String randomKey() {
|
||||
try {
|
||||
return jedis.randomKey();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rename(String oldName, String newName) {
|
||||
try {
|
||||
return (JedisUtils.OK_CODE.equals(jedis.rename(oldName, newName)));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renameNx(String oldName, String newName) {
|
||||
try {
|
||||
return (JedisUtils.OK_CODE.equals(jedis.renamenx(oldName, newName)));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void select(int dbIndex) {
|
||||
try {
|
||||
jedis.select(dbIndex);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ttl(String key) {
|
||||
try {
|
||||
return jedis.ttl(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType type(String key) {
|
||||
try {
|
||||
return DataType.fromCode(jedis.type(key));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unwatch() {
|
||||
try {
|
||||
jedis.unwatch();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(String... keys) {
|
||||
try {
|
||||
for (String key : keys) {
|
||||
jedis.watch(key);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hSet(String key, String field, String value) {
|
||||
try {
|
||||
return jedis.hset(key, field, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lPush(String key, String value) {
|
||||
try {
|
||||
return jedis.lpush(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rPush(String key, String value) {
|
||||
try {
|
||||
return jedis.rpush(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(String key) {
|
||||
try {
|
||||
return jedis.get(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String key, String value) {
|
||||
try {
|
||||
jedis.set(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis.core.connection.jedis;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.datastore.redis.core.connection.RedisConnection;
|
||||
import org.springframework.datastore.redis.core.connection.RedisConnectionFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisShardInfo;
|
||||
|
||||
/**
|
||||
* Connection factory using Jedis underneath.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class JedisConnectionFactory implements InitializingBean, DisposableBean, RedisConnectionFactory {
|
||||
|
||||
private final static Log log = LogFactory.getLog(JedisConnectionFactory.class);
|
||||
|
||||
private JedisShardInfo shardInfo;
|
||||
private String password;
|
||||
private int timeout;
|
||||
|
||||
private boolean usePool = true;
|
||||
|
||||
private JedisPool pool = null;
|
||||
// taken from Jedis code
|
||||
private int poolSize = 10;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JedisConnectionFactory</code> instance.
|
||||
*/
|
||||
public JedisConnectionFactory() {
|
||||
this(getDefaultHostName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JedisConnectionFactory</code> instance.
|
||||
*
|
||||
* @param hostname
|
||||
*/
|
||||
public JedisConnectionFactory(String hostName) {
|
||||
Assert.hasText(hostName);
|
||||
shardInfo = new JedisShardInfo(hostName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JedisConnectionFactory</code> instance.
|
||||
*
|
||||
* @param hostname
|
||||
* @param port
|
||||
*/
|
||||
public JedisConnectionFactory(String hostName, int port) {
|
||||
shardInfo = new JedisShardInfo(hostName, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JedisConnectionFactory</code> instance.
|
||||
*
|
||||
* @param shardInfo
|
||||
*/
|
||||
public JedisConnectionFactory(JedisShardInfo shardInfo) {
|
||||
this.shardInfo = shardInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Jedis instance to be used as a Redis connection.
|
||||
* The instance can be newly created or retrieved from a pool.
|
||||
*
|
||||
* @return Jedis instance ready for wrapping into a {@link RedisConnection}.
|
||||
*/
|
||||
protected Jedis fetchJedisConnector() {
|
||||
try {
|
||||
if (usePool) {
|
||||
return pool.getResource();
|
||||
}
|
||||
return new Jedis(getShardInfo());
|
||||
} catch (TimeoutException ex) {
|
||||
throw JedisUtils.convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
if (StringUtils.hasLength(password)) {
|
||||
shardInfo.setPassword(password);
|
||||
}
|
||||
|
||||
if (timeout > 0) {
|
||||
shardInfo.setTimeout(timeout);
|
||||
}
|
||||
|
||||
if (usePool) {
|
||||
int size = getPoolSize();
|
||||
pool = new JedisPool(shardInfo);
|
||||
pool.setResourcesNumber(size);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
// TODO: should this component do tracking of all returned connections
|
||||
// normally not but then again we're the ones creating the connections
|
||||
// so we end up behaving like a pool
|
||||
}
|
||||
|
||||
public JedisConnection getConnection() {
|
||||
return new JedisConnection(fetchJedisConnector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
return JedisUtils.convertJedisAccessException(ex);
|
||||
}
|
||||
|
||||
private static String getDefaultHostName() {
|
||||
String temp;
|
||||
try {
|
||||
InetAddress localMachine = InetAddress.getLocalHost();
|
||||
temp = localMachine.getHostName();
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Using hostname [" + temp + "] for hostname.");
|
||||
} catch (UnknownHostException e) {
|
||||
log.warn("Could not get host name, using 'localhost' as default value", e);
|
||||
temp = "localhost";
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the password
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param password the password to set
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shardInfo.
|
||||
*
|
||||
* @return Returns the shardInfo
|
||||
*/
|
||||
public JedisShardInfo getShardInfo() {
|
||||
return shardInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param shardInfo The shardInfo to set.
|
||||
*/
|
||||
public void setShardInfo(JedisShardInfo shardInfo) {
|
||||
this.shardInfo = shardInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timeout.
|
||||
*
|
||||
* @return Returns the timeout
|
||||
*/
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timeout The timeout to set.
|
||||
*/
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the use of a connection pool.
|
||||
*
|
||||
* @return Returns the use of connection pooling.
|
||||
*/
|
||||
public boolean isPooling() {
|
||||
return usePool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on or off the use of connection pooling.
|
||||
*
|
||||
* @param usePool The usePool to set.
|
||||
*/
|
||||
public void setPooling(boolean usePool) {
|
||||
this.usePool = usePool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the poolSize.
|
||||
*
|
||||
* @return Returns the poolSize
|
||||
*/
|
||||
public int getPoolSize() {
|
||||
return poolSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param poolSize The poolSize to set.
|
||||
*/
|
||||
public void setPoolSize(int poolSize) {
|
||||
Assert.isTrue(poolSize > 0, "pool size needs to be bigger then zero");
|
||||
this.poolSize = poolSize;
|
||||
usePool = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis.core.connection.jedis;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.datastore.redis.RedisConnectionFailureException;
|
||||
import org.springframework.datastore.redis.UncategorizedRedisException;
|
||||
|
||||
import redis.clients.jedis.JedisException;
|
||||
|
||||
/**
|
||||
* Helper class featuring methods for Jedis connection handling, providing support for exception translation.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public abstract class JedisUtils {
|
||||
|
||||
public static final String OK_CODE = "OK";
|
||||
|
||||
public static DataAccessException convertJedisAccessException(JedisException ex) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
public static DataAccessException convertJedisAccessException(RuntimeException ex) {
|
||||
if (ex instanceof JedisException) {
|
||||
return convertJedisAccessException((JedisException) ex);
|
||||
}
|
||||
|
||||
return new UncategorizedRedisException("Unknown exception", ex);
|
||||
}
|
||||
|
||||
static DataAccessException convertJedisAccessException(IOException ex) {
|
||||
if (ex instanceof UnknownHostException) {
|
||||
return new RedisConnectionFailureException("Unknown host " + ex.getMessage(), ex);
|
||||
}
|
||||
return new RedisConnectionFailureException("Could not connect to Redis server", ex);
|
||||
}
|
||||
|
||||
static DataAccessException convertJedisAccessException(TimeoutException ex) {
|
||||
throw new RedisConnectionFailureException("Jedis pool timed out. Could not get Redis Connection", ex);
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis.core.jedis;
|
||||
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.datastore.redis.CannotGetRedisConnectionException;
|
||||
import org.springframework.datastore.redis.core.AbstractRedisClientFactory;
|
||||
import org.springframework.datastore.redis.core.RedisClient;
|
||||
import org.springframework.datastore.redis.support.RedisPersistenceExceptionTranslator;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
|
||||
/**
|
||||
* A RedisClientFactory implementation that uses Jedis's native connection/client
|
||||
* caching features.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*/
|
||||
public class CachingJedisClientFactory extends AbstractRedisClientFactory {
|
||||
|
||||
private JedisPool pool;
|
||||
|
||||
private int timeout;
|
||||
|
||||
private int clientCacheSize;
|
||||
|
||||
private long maxWaitTime;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param clientCacheSize
|
||||
*/
|
||||
public CachingJedisClientFactory(int clientCacheSize) {
|
||||
this.clientCacheSize = clientCacheSize;
|
||||
}
|
||||
|
||||
public CachingJedisClientFactory(JedisPool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public int getClientCacheSize() {
|
||||
return this.clientCacheSize;
|
||||
}
|
||||
|
||||
public JedisPool getJedisPool() {
|
||||
return this.pool;
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
protected void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public long getMaxWaitTime() {
|
||||
return this.maxWaitTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum amount of time (in milliseconds) the getResource() method
|
||||
* should block before throwing an TimeoutException.
|
||||
* @param maxWaitTime The maximum time you would like to wait for the resource.
|
||||
*/
|
||||
public void setMaxWaitTime(long maxWaitTime) {
|
||||
this.maxWaitTime = maxWaitTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisClient doGetClient() {
|
||||
Jedis jedis;
|
||||
if (getClientCacheSize() != 0) {
|
||||
pool = new JedisPool(getHostName(), getPort(), getTimeout());
|
||||
pool.setResourcesNumber(getClientCacheSize());
|
||||
}
|
||||
try {
|
||||
if (getMaxWaitTime() != 0)
|
||||
jedis = pool.getResource(getMaxWaitTime());
|
||||
else {
|
||||
jedis = pool.getResource();
|
||||
}
|
||||
} catch (TimeoutException e) {
|
||||
throw new CannotGetRedisConnectionException(
|
||||
"Timed out. Could not get Redis Connection", e);
|
||||
}
|
||||
return new JedisClient(jedis, getExceptionTranslator() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisPersistenceExceptionTranslator getExceptionTranslator() {
|
||||
return new JedisPersistenceExceptionTranslator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,535 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis.core.jedis;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.datastore.redis.core.AbstractRedisClient;
|
||||
import org.springframework.datastore.redis.support.RedisPersistenceExceptionTranslator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
/**
|
||||
* Jedis based implementation of Spring's RedisClient interface. Presents a low
|
||||
* level API where method names map onto Redis commands.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*/
|
||||
public class JedisClient extends AbstractRedisClient {
|
||||
|
||||
private Jedis _jedis;
|
||||
private RedisPersistenceExceptionTranslator exceptionTranslator;
|
||||
|
||||
public JedisClient(Jedis jedis,
|
||||
RedisPersistenceExceptionTranslator exceptionTranslator) {
|
||||
this._jedis = jedis;
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
}
|
||||
|
||||
public <T> T execute(JedisClientCallback<T> action) {
|
||||
Assert.notNull(action, "Callback object must not be null");
|
||||
|
||||
// TODO jredisClient resource mgmt.
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing callback on Jedis : " + _jedis);
|
||||
}
|
||||
return action.doInJedis(_jedis);
|
||||
} catch (Exception e) {
|
||||
throw convertJedisAccessException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected DataAccessException convertJedisAccessException(Exception ex) {
|
||||
return exceptionTranslator.translateException(ex);
|
||||
}
|
||||
|
||||
public void disconnect() throws IOException {
|
||||
execute(new JedisClientCallback<Object>() {
|
||||
public Object doInJedis(Jedis jedis) throws Exception {
|
||||
jedis.disconnect();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Database control commands
|
||||
|
||||
public String save() {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.save();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String bgsave() {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.bgsave();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String bgrewriteaof() {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.bgrewriteaof();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer lastsave() {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.lastsave();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String shutdown() {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.shutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Map<String, String> info() {
|
||||
return execute(new JedisClientCallback<Map<String, String>>() {
|
||||
public Map<String, String> doInJedis(Jedis jedis) throws Exception {
|
||||
String[] response = StringUtils.delimitedListToStringArray(
|
||||
jedis.info(), "\r\n");
|
||||
Map<String, String> responseMap = new HashMap<String, String>();
|
||||
for (String responseLine : response) {
|
||||
if (!responseLine.isEmpty()) {
|
||||
String[] keyValue = StringUtils
|
||||
.split(responseLine, ":");
|
||||
if (keyValue == null) {
|
||||
logger.warn("Could not parse info reponse line ["
|
||||
+ responseLine + "]");
|
||||
continue;
|
||||
}
|
||||
responseMap.put(keyValue[0], keyValue[1]);
|
||||
}
|
||||
}
|
||||
return responseMap;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String slaveof(final String host, final int port) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.slaveof(host, port);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String slaveofNoOne() {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.slaveofNoOne();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String select(final int index) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.select(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String flushDb() {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.flushDB();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String flushAll() {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.flushAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer move(final String key, final int dbIndex) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.move(key, dbIndex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String auth(final String password) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.auth(password);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer dbSize() {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.dbSize();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Commands operating on string value types "StringOperations" or
|
||||
// "Operations"
|
||||
|
||||
public void set(final String key, final String value) {
|
||||
execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.set(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void set(String key, byte[] value) {
|
||||
set(key, byteToString(value));
|
||||
}
|
||||
|
||||
public String get(final String key) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.get(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public byte[] getAsBytes(String key) {
|
||||
return stringToByte(get(key));
|
||||
}
|
||||
|
||||
public String getSet(final String key, final String value) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.getSet(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<String> mget(final String... keys) {
|
||||
return execute(new JedisClientCallback<List<String>>() {
|
||||
public List<String> doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.mget(keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer setnx(final String key, final String value) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.setnx(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String setex(final String key, final int seconds, final String value) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.setex(key, seconds, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String mset(final String... keysvalues) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.mset(keysvalues);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer msetnx(final String... keysvalues) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.msetnx(keysvalues);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer incrBy(final String key, final int increment) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.incrBy(key, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer incr(final String key) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.incr(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer decr(final String key) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.decr(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer decrBy(final String key, final int increment) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.decrBy(key, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer append(final String key, final String value) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.append(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String substr(final String key, final int start, final int end) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.substr(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Commands operating on all value types "KeySpaceOperations"
|
||||
|
||||
public Integer exists(final String key) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.exists(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer del(final String... keys) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.del(keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String type(final String key) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.type(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<String> keys(final String pattern) {
|
||||
return execute(new JedisClientCallback<List<String>>() {
|
||||
public List<String> doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.keys(pattern);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String randomKey() {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.randomKey();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String rename(final String oldkey, final String newkey) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.rename(oldkey, newkey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer renamenx(final String oldkey, final String newkey) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.renamenx(oldkey, newkey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer expire(final String key, final int seconds) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.expire(key, seconds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer expireAt(final String key, final long unixTime) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.expireAt(key, unixTime);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer ttl(final String key) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.ttl(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer persist(final String key) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.persist(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Commands operating on Sets
|
||||
|
||||
public Integer sadd(final String key, final String member) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.sadd(key, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> smembers(final String key) {
|
||||
return execute(new JedisClientCallback<Set<String>>() {
|
||||
public Set<String> doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.smembers(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer srem(final String key, final String member) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.srem(key, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String spop(final String key) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.spop(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer smove(final String srckey, final String dstkey,
|
||||
final String member) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.smove(srckey, dstkey, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer scard(final String key) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.scard(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer sismember(final String key, final String member) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.sismember(key, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> sinter(final String... keys) {
|
||||
return execute(new JedisClientCallback<Set<String>>() {
|
||||
public Set<String> doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.sinter(keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer sinterstore(final String dstkey, final String... keys) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.sinterstore(dstkey, keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> sunion(final String... keys) {
|
||||
return execute(new JedisClientCallback<Set<String>>() {
|
||||
public Set<String> doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.sunion(keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer sunionstore(final String dstkey, final String... keys) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.sunionstore(dstkey, keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> sdiff(final String... keys) {
|
||||
return execute(new JedisClientCallback<Set<String>>() {
|
||||
public Set<String> doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.sdiff(keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Integer sdiffstore(final String dstkey, final String... keys) {
|
||||
return execute(new JedisClientCallback<Integer>() {
|
||||
public Integer doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.sdiffstore(dstkey, keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String srandmember(final String key) {
|
||||
return execute(new JedisClientCallback<String>() {
|
||||
public String doInJedis(Jedis jedis) throws Exception {
|
||||
return jedis.srandmember(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis.core.jedis;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
/**
|
||||
* Basic callback for use in JedisClient
|
||||
* @author Mark Pollack
|
||||
*
|
||||
* @param <T> TODO
|
||||
*/
|
||||
public interface JedisClientCallback<T> {
|
||||
|
||||
/**
|
||||
* Execute any number of operations against the supplied Jedis
|
||||
* {@link Jedis}, possibly returning a result.
|
||||
*/
|
||||
T doInJedis(Jedis jedis) throws Exception;
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis.core.jedis;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.springframework.datastore.redis.CannotGetRedisConnectionException;
|
||||
import org.springframework.datastore.redis.core.AbstractRedisClientFactory;
|
||||
import org.springframework.datastore.redis.core.RedisClient;
|
||||
import org.springframework.datastore.redis.core.RedisClientFactory;
|
||||
import org.springframework.datastore.redis.core.jredis.JRedisPersistenceExceptionTranslator;
|
||||
import org.springframework.datastore.redis.support.RedisPersistenceExceptionTranslator;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisShardInfo;
|
||||
import redis.clients.util.ShardInfo;
|
||||
|
||||
/**
|
||||
* A {@link RedisClientFactory} implementation that returns a new instance of a
|
||||
* Jedis backed RedisClient from call {@link #createClient()} calls.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*/
|
||||
public class JedisClientFactory extends AbstractRedisClientFactory {
|
||||
|
||||
private JedisShardInfo shardInfo;
|
||||
|
||||
private int timeout;
|
||||
|
||||
private RedisPersistenceExceptionTranslator exceptionTranslator = new JRedisPersistenceExceptionTranslator();
|
||||
|
||||
public JedisClientFactory() {
|
||||
setHostName(getDefaultHostName());
|
||||
}
|
||||
|
||||
public JedisClientFactory(String hostname) {
|
||||
setHostName(hostname);
|
||||
}
|
||||
|
||||
public JedisClientFactory(String hostname, int port)
|
||||
{
|
||||
setHostName(hostname);
|
||||
setPort(port);
|
||||
}
|
||||
|
||||
public JedisClientFactory(String hostname, int port, int timeout)
|
||||
{
|
||||
setHostName(hostname);
|
||||
setPort(port);
|
||||
setTimeout(timeout);
|
||||
}
|
||||
|
||||
public JedisClientFactory(JedisShardInfo shardInfo) {
|
||||
this.shardInfo = shardInfo;
|
||||
}
|
||||
|
||||
protected JedisShardInfo getShardInfo() {
|
||||
return this.shardInfo;
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
protected void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisClient doGetClient() {
|
||||
Jedis jedis;
|
||||
if (getShardInfo() != null) {
|
||||
jedis = new Jedis(getShardInfo());
|
||||
}
|
||||
if (getPort() != 0 && getTimeout() != 0) {
|
||||
jedis = new Jedis(getHostName(), getPort(), getTimeout());
|
||||
} else if (getPort() != 0) {
|
||||
jedis = new Jedis(getHostName(), getPort());
|
||||
} else {
|
||||
jedis = new Jedis(getHostName());
|
||||
}
|
||||
try {
|
||||
jedis.connect();
|
||||
if (getPassword() != null) {
|
||||
jedis.auth(getPassword());
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
throw new CannotGetRedisConnectionException(
|
||||
"Could not get Redis Connection", e);
|
||||
} catch (IOException e) {
|
||||
throw new CannotGetRedisConnectionException(
|
||||
"Could not get Redis Connection", e);
|
||||
}
|
||||
return new JedisClient(jedis, getExceptionTranslator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisPersistenceExceptionTranslator getExceptionTranslator() {
|
||||
return exceptionTranslator;
|
||||
}
|
||||
|
||||
public void setExceptionTranslator(
|
||||
RedisPersistenceExceptionTranslator exceptionTranslator) {
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 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.datastore.redis.core.jedis;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.datastore.redis.support.RedisPersistenceExceptionTranslator;
|
||||
|
||||
/**
|
||||
* Translates error messages from Jedis to Spring's Data Access exception class hierarchy
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*/
|
||||
public class JedisPersistenceExceptionTranslator implements RedisPersistenceExceptionTranslator,
|
||||
PersistenceExceptionTranslator {
|
||||
|
||||
public DataAccessException translateException(Exception ex) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user