/*
* 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 org.springframework.data.redis.connection.jedis;
import java.util.List;
import java.util.Properties;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.jedis.JedisConnection.JedisResult;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
/**
* @author Mark Paluch
* @since 2.0
*/
class JedisServerCommands implements RedisServerCommands {
private static final String SHUTDOWN_SCRIPT = "return redis.call('SHUTDOWN','%s')";
private final JedisConnection connection;
public JedisServerCommands(JedisConnection connection) {
this.connection = connection;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgReWriteAof()
*/
@Override
public void bgReWriteAof() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().bgrewriteaof()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().bgrewriteaof()));
return;
}
connection.getJedis().bgrewriteaof();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgSave()
*/
@Override
public void bgSave() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().bgsave()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().bgsave()));
return;
}
connection.getJedis().bgsave();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#lastSave()
*/
@Override
public Long lastSave() {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().lastsave()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().lastsave()));
return null;
}
return connection.getJedis().lastsave();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#save()
*/
@Override
public void save() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().save()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().save()));
return;
}
connection.getJedis().save();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#dbSize()
*/
@Override
public Long dbSize() {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().dbSize()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().dbSize()));
return null;
}
return connection.getJedis().dbSize();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushDb()
*/
@Override
public void flushDb() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().flushDB()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().flushDB()));
return;
}
connection.getJedis().flushDB();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushAll()
*/
@Override
public void flushAll() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().flushAll()));
return;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().flushAll()));
return;
}
connection.getJedis().flushAll();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info()
*/
@Override
public Properties info() {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().info(), JedisConverters.stringToProps()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().info(), JedisConverters.stringToProps()));
return null;
}
return JedisConverters.toProperties(connection.getJedis().info());
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info(java.lang.String)
*/
@Override
public Properties info(String section) {
if (isPipelined()) {
throw new UnsupportedOperationException();
}
if (isQueueing()) {
throw new UnsupportedOperationException();
}
try {
return JedisConverters.toProperties(connection.getJedis().info(section));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown()
*/
@Override
public void shutdown() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().shutdown()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().shutdown()));
return;
}
connection.getJedis().shutdown();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown(org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption)
*/
@Override
public void shutdown(ShutdownOption option) {
if (option == null) {
shutdown();
return;
}
connection.eval(String.format(SHUTDOWN_SCRIPT, option.name()).getBytes(), ReturnType.STATUS, 0);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getConfig(java.lang.String)
*/
@Override
public List<String> getConfig(String param) {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().configGet(param)));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().configGet(param)));
return null;
}
return connection.getJedis().configGet(param);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setConfig(java.lang.String, java.lang.String)
*/
@Override
public void setConfig(String param, String value) {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().configSet(param, value)));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().configSet(param, value)));
return;
}
connection.getJedis().configSet(param, value);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#resetConfigStats()
*/
@Override
public void resetConfigStats() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().configResetStat()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().configResetStat()));
return;
}
connection.getJedis().configResetStat();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#time()
*/
@Override
public Long time() {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().time(), JedisConverters.toTimeConverter()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().time(), JedisConverters.toTimeConverter()));
return null;
}
return JedisConverters.toTimeConverter().convert(connection.getJedis().time());
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#killClient(java.lang.String, int)
*/
@Override
public void killClient(String host, int port) {
Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'CLIENT KILL' is not supported in transaction / pipline mode.");
}
try {
this.connection.getJedis().clientKill(String.format("%s:%s", host, port));
} catch (Exception e) {
throw convertJedisAccessException(e);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setClientName(byte[])
*/
@Override
public void setClientName(byte[] name) {
if (isPipelined() || isQueueing()) {
throw new UnsupportedOperationException("'CLIENT SETNAME' is not suppored in transacton / pipeline mode.");
}
connection.getJedis().clientSetname(name);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientName()
*/
@Override
public String getClientName() {
if (isPipelined() || isQueueing()) {
throw new UnsupportedOperationException();
}
return connection.getJedis().clientGetname();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientList()
*/
@Override
public List<RedisClientInfo> getClientList() {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'CLIENT LIST' is not supported in in pipeline / multi mode.");
}
return JedisConverters.toListOfRedisClientInformation(this.connection.getJedis().clientList());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOf(java.lang.String, int)
*/
@Override
public void slaveOf(String host, int port) {
Assert.hasText(host, "Host must not be null for 'SLAVEOF' command.");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'SLAVEOF' cannot be called in pipline / transaction mode.");
}
try {
this.connection.getJedis().slaveof(host, port);
} catch (Exception e) {
throw convertJedisAccessException(e);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOfNoOne()
*/
@Override
public void slaveOfNoOne() {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'SLAVEOF' cannot be called in pipline / transaction mode.");
}
try {
this.connection.getJedis().slaveofNoOne();
} catch (Exception e) {
throw convertJedisAccessException(e);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option) {
migrate(key, target, dbIndex, option, Long.MAX_VALUE);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption, long)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option, long timeout) {
final int timeoutToUse = timeout <= Integer.MAX_VALUE ? (int) timeout : Integer.MAX_VALUE;
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().migrate(JedisConverters.toBytes(target.getHost()),
target.getPort(), key, dbIndex, timeoutToUse)));
return;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction()
.migrate(JedisConverters.toBytes(target.getHost()), target.getPort(), key, dbIndex, timeoutToUse)));
return;
}
connection.getJedis().migrate(JedisConverters.toBytes(target.getHost()), target.getPort(), key, dbIndex,
timeoutToUse);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
private boolean isPipelined() {
return connection.isPipelined();
}
private void pipeline(JedisResult result) {
connection.pipeline(result);
}
private boolean isQueueing() {
return connection.isQueueing();
}
private void transaction(JedisResult result) {
connection.transaction(result);
}
private RuntimeException convertJedisAccessException(Exception ex) {
return connection.convertJedisAccessException(ex);
}
}