/* * 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.Arrays; import java.util.Collections; import java.util.List; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.ClusterSlotHashUtil; import org.springframework.data.redis.connection.RedisListCommands; import org.springframework.data.redis.connection.jedis.JedisClusterConnection.JedisMultiKeyClusterCommandCallback; import org.springframework.util.CollectionUtils; /** * @author Christoph Strobl * @since 2.0 */ class JedisClusterListCommands implements RedisListCommands { private final JedisClusterConnection connection; public JedisClusterListCommands(JedisClusterConnection connection) { this.connection = connection; } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#rPush(byte[], byte[][]) */ @Override public Long rPush(byte[] key, byte[]... values) { try { return connection.getCluster().rpush(key, values); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lPush(byte[], byte[][]) */ @Override public Long lPush(byte[] key, byte[]... values) { try { return connection.getCluster().lpush(key, values); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#rPushX(byte[], byte[]) */ @Override public Long rPushX(byte[] key, byte[] value) { try { return connection.getCluster().rpushx(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lPushX(byte[], byte[]) */ @Override public Long lPushX(byte[] key, byte[] value) { try { return connection.getCluster().lpushx(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lLen(byte[]) */ @Override public Long lLen(byte[] key) { try { return connection.getCluster().llen(key); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lRange(byte[], long, long) */ @Override public List<byte[]> lRange(byte[] key, long begin, long end) { try { return connection.getCluster().lrange(key, begin, end); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lTrim(byte[], long, long) */ @Override public void lTrim(final byte[] key, final long begin, final long end) { try { connection.getCluster().ltrim(key, begin, end); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lIndex(byte[], long) */ @Override public byte[] lIndex(byte[] key, long index) { try { return connection.getCluster().lindex(key, index); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lInsert(byte[], org.springframework.data.redis.connection.RedisListCommands.Position, byte[], byte[]) */ @Override public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { try { return connection.getCluster().linsert(key, JedisConverters.toListPosition(where), pivot, value); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lSet(byte[], long, byte[]) */ @Override public void lSet(byte[] key, long index, byte[] value) { try { connection.getCluster().lset(key, index, value); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lRem(byte[], long, byte[]) */ @Override public Long lRem(byte[] key, long count, byte[] value) { try { return connection.getCluster().lrem(key, count, value); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#lPop(byte[]) */ @Override public byte[] lPop(byte[] key) { try { return connection.getCluster().lpop(key); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#rPop(byte[]) */ @Override public byte[] rPop(byte[] key) { try { return connection.getCluster().rpop(key); } catch (Exception ex) { throw convertJedisAccessException(ex); } } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#bLPop(int, byte[][]) */ @Override public List<byte[]> bLPop(final int timeout, final byte[]... keys) { if (ClusterSlotHashUtil.isSameSlotForAllKeys(keys)) { try { return connection.getCluster().blpop(timeout, keys); } catch (Exception ex) { throw convertJedisAccessException(ex); } } return connection.getClusterCommandExecutor() .executeMuliKeyCommand( (JedisMultiKeyClusterCommandCallback<List<byte[]>>) (client, key) -> client.blpop(timeout, key), Arrays.asList(keys)) .getFirstNonNullNotEmptyOrDefault(Collections.<byte[]> emptyList()); } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#bRPop(int, byte[][]) */ @Override public List<byte[]> bRPop(final int timeout, byte[]... keys) { return connection.getClusterCommandExecutor() .executeMuliKeyCommand( (JedisMultiKeyClusterCommandCallback<List<byte[]>>) (client, key) -> client.brpop(timeout, key), Arrays.asList(keys)) .getFirstNonNullNotEmptyOrDefault(Collections.<byte[]> emptyList()); } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#rPopLPush(byte[], byte[]) */ @Override public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { if (ClusterSlotHashUtil.isSameSlotForAllKeys(srcKey, dstKey)) { try { return connection.getCluster().rpoplpush(srcKey, dstKey); } catch (Exception ex) { throw convertJedisAccessException(ex); } } byte[] val = rPop(srcKey); lPush(dstKey, val); return val; } /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisListCommands#bRPopLPush(int, byte[], byte[]) */ @Override public byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey) { if (ClusterSlotHashUtil.isSameSlotForAllKeys(srcKey, dstKey)) { try { return connection.getCluster().brpoplpush(srcKey, dstKey, timeout); } catch (Exception ex) { throw convertJedisAccessException(ex); } } List<byte[]> val = bRPop(timeout, srcKey); if (!CollectionUtils.isEmpty(val)) { lPush(dstKey, val.get(1)); return val.get(1); } return null; } private DataAccessException convertJedisAccessException(Exception ex) { return connection.convertJedisAccessException(ex); } }