/* * 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); } }