org.crazycake.shiro.common.AbstractLettuceRedisManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of shiro-redis Show documentation
Show all versions of shiro-redis Show documentation
shiro only provide the support of ehcache and
concurrentHashMap. Here is an implement of redis cache can be used by
shiro. Hope it will help you!
The newest version!
package org.crazycake.shiro.common;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.sync.RedisCommands;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.crazycake.shiro.IRedisManager;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @author Teamo
* @since 2022/05/19
*/
public abstract class AbstractLettuceRedisManager implements IRedisManager {
/**
* Default value of count.
*/
private static final int DEFAULT_COUNT = 100;
/**
* timeout for RedisClient try to connect to redis server, not expire time! unit seconds.
*/
private Duration timeout = RedisURI.DEFAULT_TIMEOUT_DURATION;
/**
* Redis database.
*/
private int database = 0;
/**
* Redis password.
*/
private String password;
/**
* Whether to enable async.
*/
private boolean isAsync = true;
/**
* The number of elements returned at every iteration.
*/
private int count = DEFAULT_COUNT;
/**
* ClientOptions used to initialize RedisClient.
*/
private ClientOptions clientOptions = ClientOptions.create();
/**
* genericObjectPoolConfig used to initialize GenericObjectPoolConfig object.
*/
@SuppressWarnings("rawtypes")
private GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig<>();
/**
* Get a stateful connection.
*
* @return T
*/
@SuppressWarnings("rawtypes")
protected abstract StatefulRedisConnection getStatefulConnection();
public Duration getTimeout() {
return timeout;
}
public void setTimeout(Duration timeout) {
this.timeout = timeout;
}
public int getDatabase() {
return database;
}
public void setDatabase(int database) {
this.database = database;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isAsync() {
return isAsync;
}
public void setIsAsync(boolean isAsync) {
this.isAsync = isAsync;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public ClientOptions getClientOptions() {
return clientOptions;
}
public void setClientOptions(ClientOptions clientOptions) {
this.clientOptions = clientOptions;
}
public GenericObjectPoolConfig> getGenericObjectPoolConfig() {
return genericObjectPoolConfig;
}
public void setGenericObjectPoolConfig(GenericObjectPoolConfig> genericObjectPoolConfig) {
this.genericObjectPoolConfig = genericObjectPoolConfig;
}
@Override
@SuppressWarnings("unchecked")
public byte[] get(byte[] key) {
if (key == null) {
return null;
}
byte[] value = null;
try (StatefulRedisConnection connect = getStatefulConnection()) {
if (isAsync) {
RedisAsyncCommands async = connect.async();
RedisFuture redisFuture = async.get(key);
value = LettuceFutures.awaitOrCancel(redisFuture, timeout.getSeconds(), TimeUnit.SECONDS);
} else {
RedisCommands sync = connect.sync();
value = sync.get(key);
}
}
return value;
}
@Override
@SuppressWarnings({"unchecked"})
public byte[] set(byte[] key, byte[] value, int expire) {
if (key == null) {
return null;
}
try (StatefulRedisConnection connect = getStatefulConnection()) {
if (isAsync) {
RedisAsyncCommands async = connect.async();
if (expire > 0) {
async.set(key, value, SetArgs.Builder.ex(expire));
} else {
async.set(key, value);
}
} else {
RedisCommands sync = connect.sync();
if (expire > 0) {
sync.set(key, value, SetArgs.Builder.ex(expire));
} else {
sync.set(key, value);
}
}
}
return value;
}
@Override
@SuppressWarnings("unchecked")
public void del(byte[] key) {
try (StatefulRedisConnection connect = getStatefulConnection()) {
if (isAsync) {
RedisAsyncCommands async = connect.async();
async.del(key);
} else {
RedisCommands sync = connect.sync();
sync.del(key);
}
}
}
@Override
@SuppressWarnings("unchecked")
public Long dbSize(byte[] pattern) {
long dbSize = 0L;
KeyScanCursor scanCursor = new KeyScanCursor<>();
scanCursor.setCursor(ScanCursor.INITIAL.getCursor());
ScanArgs scanArgs = ScanArgs.Builder.matches(pattern).limit(count);
try (StatefulRedisConnection connect = getStatefulConnection()) {
while (!scanCursor.isFinished()) {
scanCursor = getKeyScanCursor(connect, scanCursor, scanArgs);
dbSize += scanCursor.getKeys().size();
}
}
return dbSize;
}
@Override
@SuppressWarnings("unchecked")
public Set keys(byte[] pattern) {
Set keys = new HashSet<>();
KeyScanCursor scanCursor = new KeyScanCursor<>();
scanCursor.setCursor(ScanCursor.INITIAL.getCursor());
ScanArgs scanArgs = ScanArgs.Builder.matches(pattern).limit(count);
try (StatefulRedisConnection connect = getStatefulConnection()) {
while (!scanCursor.isFinished()) {
scanCursor = getKeyScanCursor(connect, scanCursor, scanArgs);
keys.addAll(scanCursor.getKeys());
}
}
return keys;
}
/**
* get scan cursor result
*
* @param connect connection
* @param scanCursor scan cursor
* @param scanArgs scan param
* @return KeyScanCursor
*/
private KeyScanCursor getKeyScanCursor(final StatefulRedisConnection connect,
KeyScanCursor scanCursor,
ScanArgs scanArgs) {
if (isAsync) {
RedisAsyncCommands async = connect.async();
scanCursor = LettuceFutures.awaitOrCancel(async.scan(scanCursor, scanArgs), timeout.getSeconds(), TimeUnit.SECONDS);
} else {
RedisCommands sync = connect.sync();
scanCursor = sync.scan(scanCursor, scanArgs);
}
return scanCursor;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy