diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java index 821c785fb..ec637b583 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java @@ -15,10 +15,12 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; import redis.clients.jedis.BinaryJedisPubSub; import redis.clients.jedis.Client; import redis.clients.jedis.Connection; import redis.clients.jedis.Jedis; +import redis.clients.jedis.MultiKeyPipelineBase; import redis.clients.jedis.Pipeline; import redis.clients.jedis.Response; import redis.clients.jedis.Transaction; @@ -30,6 +32,7 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Queue; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -69,19 +72,25 @@ public class JedisConnection extends AbstractRedisConnection { JedisConverters.exceptionConverter()); private final Jedis jedis; - private @Nullable Transaction transaction; + + private final JedisInvoker invoker = new JedisInvoker((directFunction, pipelineFunction, converter, + nullDefault) -> doInvoke(false, directFunction, pipelineFunction, converter, nullDefault)); + private final JedisInvoker statusInvoker = new JedisInvoker((directFunction, pipelineFunction, converter, + nullDefault) -> doInvoke(true, directFunction, pipelineFunction, converter, nullDefault)); + private final @Nullable Pool pool; - /** - * flag indicating whether the connection needs to be dropped or not - */ - private volatile @Nullable JedisSubscription subscription; - private volatile @Nullable Pipeline pipeline; private final int dbIndex; private final String clientName; - private boolean convertPipelineAndTxResults = true; + private List pipelinedResults = new ArrayList<>(); private Queue>> txResults = new LinkedList<>(); + private volatile @Nullable JedisSubscription subscription; + private volatile @Nullable Transaction transaction; + private volatile @Nullable Pipeline pipeline; + + private boolean convertPipelineAndTxResults = true; + /** * Constructs a new JedisConnection instance. * @@ -131,6 +140,37 @@ public class JedisConnection extends AbstractRedisConnection { } } + @Nullable + private Object doInvoke(boolean status, Function directFunction, + Function> pipelineFunction, Converter converter, + Supplier nullDefault) { + + return doWithJedis(it -> { + + if (isPipelined()) { + + Response response = pipelineFunction.apply(getRequiredPipeline()); + pipeline(status ? newStatusResult(response) : newJedisResult(response, converter, nullDefault)); + return null; + } + + if (isQueueing()) { + + Response response = pipelineFunction.apply(getRequiredTransaction()); + transaction(status ? newStatusResult(response) : newJedisResult(response, converter, nullDefault)); + return null; + } + + Object result = directFunction.apply(getJedis()); + + if (result == null) { + return nullDefault.get(); + } + + return converter.convert(result); + }); + } + protected DataAccessException convertJedisAccessException(Exception ex) { DataAccessException exception = EXCEPTION_TRANSLATION.translate(ex); return exception != null ? exception : new RedisSystemException(ex.getMessage(), ex); @@ -244,15 +284,16 @@ public class JedisConnection extends AbstractRedisConnection { return execute(command, args, Connection::getOne, JedisClientUtils::getResponse); } + @Nullable T execute(String command, byte[][] args, Function resultMapper, Function> pipelineResponseMapper) { Assert.hasText(command, "A valid command needs to be specified!"); Assert.notNull(args, "Arguments must not be null!"); - try { + return doWithJedis(it -> { - Client client = JedisClientUtils.sendCommand(command, args, this.jedis); + Client client = JedisClientUtils.sendCommand(command, args, it); if (isQueueing() || isPipelined()) { @@ -266,9 +307,7 @@ public class JedisConnection extends AbstractRedisConnection { return null; } return resultMapper.apply(client); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + }); } /* @@ -316,11 +355,7 @@ public class JedisConnection extends AbstractRedisConnection { */ @Override public boolean isClosed() { - try { - return !jedis.isConnected(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return doWithJedis(it -> !it.isConnected()); } /* @@ -418,19 +453,10 @@ public class JedisConnection extends AbstractRedisConnection { */ @Override public byte[] echo(byte[] message) { - try { - if (isPipelined()) { - pipeline(newJedisResult(getRequiredPipeline().echo(message))); - return null; - } - if (isQueueing()) { - transaction(newJedisResult(getRequiredTransaction().echo(message))); - return null; - } - return jedis.echo(message); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + + Assert.notNull(message, "Message must not be null"); + + return invoke().just(BinaryJedis::echo, MultiKeyPipelineBase::echo, message); } /* @@ -439,19 +465,7 @@ public class JedisConnection extends AbstractRedisConnection { */ @Override public String ping() { - try { - if (isPipelined()) { - pipeline(newJedisResult(getRequiredPipeline().ping())); - return null; - } - if (isQueueing()) { - transaction(newJedisResult(getRequiredTransaction().ping())); - return null; - } - return jedis.ping(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return invoke().just(BinaryJedis::ping, MultiKeyPipelineBase::ping); } /* @@ -540,24 +554,45 @@ public class JedisConnection extends AbstractRedisConnection { return jedis; } - JedisResult newJedisResult(Response response) { - return JedisResultBuilder.forResponse(response).build(); + /** + * Obtain a {@link JedisInvoker} to call Jedis methods on the current {@link Jedis} instance. + * + * @return the {@link JedisInvoker}. + * @since 2.5 + */ + JedisInvoker invoke() { + return invoker; } - JedisResult newJedisResult(Response response, Converter converter) { + /** + * Obtain a {@link JedisInvoker} to call Jedis methods returning a status response on the current {@link Jedis} + * instance. Status responses are not included in transactional and pipeline results. + * + * @return the {@link JedisInvoker}. + * @since 2.5 + */ + JedisInvoker invokeStatus() { + return statusInvoker; + } + + JedisResult newJedisResult(Response response) { + return JedisResultBuilder. forResponse(response).build(); + } + + JedisResult newJedisResult(Response response, Converter converter) { return JedisResultBuilder. forResponse(response).mappedWith(converter) .convertPipelineAndTxResults(convertPipelineAndTxResults).build(); } - JedisResult newJedisResult(Response response, Converter converter, Supplier defaultValue) { + JedisResult newJedisResult(Response response, Converter converter, Supplier defaultValue) { return JedisResultBuilder. forResponse(response).mappedWith(converter) .convertPipelineAndTxResults(convertPipelineAndTxResults).mapNullTo(defaultValue).build(); } - JedisStatusResult newStatusResult(Response response) { - return JedisResultBuilder.forResponse(response).buildStatusResult(); + JedisStatusResult newStatusResult(Response response) { + return JedisResultBuilder. forResponse(response).buildStatusResult(); } /* @@ -569,15 +604,15 @@ public class JedisConnection extends AbstractRedisConnection { if (isQueueing()) { return; } - try { + + doWithJedis(it -> { + if (isPipelined()) { getRequiredPipeline().multi(); return; } - this.transaction = jedis.multi(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + this.transaction = it.multi(); + }); } /* @@ -586,19 +621,7 @@ public class JedisConnection extends AbstractRedisConnection { */ @Override public void select(int dbIndex) { - try { - if (isPipelined()) { - pipeline(newStatusResult(getRequiredPipeline().select(dbIndex))); - return; - } - if (isQueueing()) { - transaction(newStatusResult(getRequiredTransaction().select(dbIndex))); - return; - } - jedis.select(dbIndex); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + invokeStatus().just(BinaryJedis::select, MultiKeyPipelineBase::select, dbIndex); } /* @@ -607,11 +630,7 @@ public class JedisConnection extends AbstractRedisConnection { */ @Override public void unwatch() { - try { - jedis.unwatch(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + doWithJedis((Consumer) BinaryJedis::unwatch); } /* @@ -623,17 +642,16 @@ public class JedisConnection extends AbstractRedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } - try { + doWithJedis(it -> { + for (byte[] key : keys) { if (isPipelined()) { pipeline(newStatusResult(getRequiredPipeline().watch(key))); } else { - jedis.watch(key); + it.watch(key); } } - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + }); } // @@ -646,19 +664,7 @@ public class JedisConnection extends AbstractRedisConnection { */ @Override public Long publish(byte[] channel, byte[] message) { - try { - if (isPipelined()) { - pipeline(newJedisResult(getRequiredPipeline().publish(channel, message))); - return null; - } - if (isQueueing()) { - transaction(newJedisResult(getRequiredTransaction().publish(channel, message))); - return null; - } - return jedis.publish(channel, message); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return invoke().just(BinaryJedis::publish, MultiKeyPipelineBase::publish, channel, message); } /* @@ -685,26 +691,23 @@ public class JedisConnection extends AbstractRedisConnection { */ @Override public void pSubscribe(MessageListener listener, byte[]... patterns) { + if (isSubscribed()) { throw new RedisSubscribedConnectionException( "Connection already subscribed; use the connection Subscription to cancel or add new channels"); } - if (isQueueing()) { - throw new UnsupportedOperationException(); - } - if (isPipelined()) { + + if (isQueueing() || isPipelined()) { throw new UnsupportedOperationException(); } - try { + doWithJedis(it -> { + BinaryJedisPubSub jedisPubSub = new JedisMessageListener(listener); subscription = new JedisSubscription(listener, jedisPubSub, null, patterns); - jedis.psubscribe(jedisPubSub, patterns); - - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + it.psubscribe(jedisPubSub, patterns); + }); } /* @@ -713,27 +716,23 @@ public class JedisConnection extends AbstractRedisConnection { */ @Override public void subscribe(MessageListener listener, byte[]... channels) { + if (isSubscribed()) { throw new RedisSubscribedConnectionException( "Connection already subscribed; use the connection Subscription to cancel or add new channels"); } - if (isQueueing()) { - throw new UnsupportedOperationException(); - } - if (isPipelined()) { + if (isQueueing() || isPipelined()) { throw new UnsupportedOperationException(); } - try { + doWithJedis(it -> { + BinaryJedisPubSub jedisPubSub = new JedisMessageListener(listener); subscription = new JedisSubscription(listener, jedisPubSub, channels, null); - jedis.subscribe(jedisPubSub, channels); - - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + it.subscribe(jedisPubSub, channels); + }); } /** @@ -753,17 +752,17 @@ public class JedisConnection extends AbstractRedisConnection { @Override protected boolean isActive(RedisNode node) { - Jedis temp = null; + Jedis verification = null; try { - temp = getJedis(node); - temp.connect(); - return temp.ping().equalsIgnoreCase("pong"); + verification = getJedis(node); + verification.connect(); + return verification.ping().equalsIgnoreCase("pong"); } catch (Exception e) { return false; } finally { - if (temp != null) { - temp.disconnect(); - temp.close(); + if (verification != null) { + verification.disconnect(); + verification.close(); } } } @@ -788,4 +787,24 @@ public class JedisConnection extends AbstractRedisConnection { return jedis; } + @Nullable + private T doWithJedis(Function callback) { + + try { + return callback.apply(getJedis()); + + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + private void doWithJedis(Consumer callback) { + + try { + callback.accept(getJedis()); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisGeoCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisGeoCommands.java index 52ac5f83c..f00b24042 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisGeoCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisGeoCommands.java @@ -15,8 +15,10 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; import redis.clients.jedis.GeoCoordinate; import redis.clients.jedis.GeoUnit; +import redis.clients.jedis.MultiKeyPipelineBase; import java.util.HashMap; import java.util.List; @@ -56,22 +58,8 @@ class JedisGeoCommands implements RedisGeoCommands { Assert.notNull(point, "Point must not be null!"); Assert.notNull(member, "Member must not be null!"); - try { - if (isPipelined()) { - pipeline(connection - .newJedisResult(connection.getRequiredPipeline().geoadd(key, point.getX(), point.getY(), member))); - return null; - } - if (isQueueing()) { - transaction(connection - .newJedisResult(connection.getRequiredTransaction().geoadd(key, point.getX(), point.getY(), member))); - return null; - } - - return connection.getJedis().geoadd(key, point.getX(), point.getY(), member); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::geoadd, MultiKeyPipelineBase::geoadd, key, point.getX(), point.getY(), + member); } /* @@ -90,20 +78,7 @@ class JedisGeoCommands implements RedisGeoCommands { redisGeoCoordinateMap.put(mapKey, JedisConverters.toGeoCoordinate(memberCoordinateMap.get(mapKey))); } - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().geoadd(key, redisGeoCoordinateMap))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().geoadd(key, redisGeoCoordinateMap))); - return null; - } - - return connection.getJedis().geoadd(key, redisGeoCoordinateMap); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::geoadd, MultiKeyPipelineBase::geoadd, key, redisGeoCoordinateMap); } /* @@ -122,20 +97,7 @@ class JedisGeoCommands implements RedisGeoCommands { redisGeoCoordinateMap.put(location.getName(), JedisConverters.toGeoCoordinate(location.getPoint())); } - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().geoadd(key, redisGeoCoordinateMap))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().geoadd(key, redisGeoCoordinateMap))); - return null; - } - - return connection.getJedis().geoadd(key, redisGeoCoordinateMap); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::geoadd, MultiKeyPipelineBase::geoadd, key, redisGeoCoordinateMap); } /* @@ -151,23 +113,8 @@ class JedisGeoCommands implements RedisGeoCommands { Converter distanceConverter = JedisConverters.distanceConverterForMetric(DistanceUnit.METERS); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().geodist(key, member1, member2), - distanceConverter)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().geodist(key, member1, member2), - distanceConverter)); - return null; - } - - Double distance = connection.getJedis().geodist(key, member1, member2); - return distance != null ? distanceConverter.convert(distance) : null; - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::geodist, MultiKeyPipelineBase::geodist, key, member1, member2) + .get(distanceConverter); } /* @@ -185,23 +132,8 @@ class JedisGeoCommands implements RedisGeoCommands { GeoUnit geoUnit = JedisConverters.toGeoUnit(metric); Converter distanceConverter = JedisConverters.distanceConverterForMetric(metric); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().geodist(key, member1, member2, geoUnit), - distanceConverter)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult( - connection.getRequiredTransaction().geodist(key, member1, member2, geoUnit), distanceConverter)); - return null; - } - - Double distance = connection.getJedis().geodist(key, member1, member2, geoUnit); - return distance != null ? distanceConverter.convert(distance) : null; - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::geodist, MultiKeyPipelineBase::geodist, key, member1, member2, geoUnit) + .get(distanceConverter); } /* @@ -215,22 +147,8 @@ class JedisGeoCommands implements RedisGeoCommands { Assert.notNull(members, "Members must not be null!"); Assert.noNullElements(members, "Members must not contain null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().geohash(key, members), - JedisConverters.bytesListToStringListConverter())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().geohash(key, members), - JedisConverters.bytesListToStringListConverter())); - return null; - } - - return JedisConverters.bytesListToStringListConverter().convert(connection.getJedis().geohash(key, members)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::geohash, MultiKeyPipelineBase::geohash, key, members) + .get(JedisConverters.bytesListToStringListConverter()); } /* @@ -245,19 +163,8 @@ class JedisGeoCommands implements RedisGeoCommands { Assert.noNullElements(members, "Members must not contain null!"); ListConverter converter = JedisConverters.geoCoordinateToPointConverter(); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().geopos(key, members), converter)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().geopos(key, members), converter)); - return null; - } - return converter.convert(connection.getJedis().geopos(key, members)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + + return connection.invoke().from(BinaryJedis::geopos, MultiKeyPipelineBase::geopos, key, members).get(converter); } /* @@ -272,30 +179,12 @@ class JedisGeoCommands implements RedisGeoCommands { Converter, GeoResults>> converter = JedisConverters .geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric()); - try { - if (isPipelined()) { - pipeline( - connection.newJedisResult( - connection.getRequiredPipeline().georadius(key, within.getCenter().getX(), within.getCenter().getY(), - within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric())), - converter)); - return null; - } - if (isQueueing()) { - transaction( - connection.newJedisResult( - connection.getRequiredTransaction().georadius(key, within.getCenter().getX(), within.getCenter().getY(), - within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric())), - converter)); - return null; - } - return converter - .convert(connection.getJedis().georadius(key, within.getCenter().getX(), within.getCenter().getY(), - within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric()))); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke() + .from(BinaryJedis::georadius, MultiKeyPipelineBase::georadius, key, within.getCenter().getX(), + within.getCenter().getY(), within.getRadius().getValue(), + JedisConverters.toGeoUnit(within.getRadius().getMetric())) + .get(converter); } /* @@ -313,26 +202,11 @@ class JedisGeoCommands implements RedisGeoCommands { Converter, GeoResults>> converter = JedisConverters .geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric()); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().georadius(key, within.getCenter().getX(), + return connection.invoke().from(BinaryJedis::georadius, MultiKeyPipelineBase::georadius, key, + within.getCenter().getX(), within.getCenter().getY(), within.getRadius().getValue(), - JedisConverters.toGeoUnit(within.getRadius().getMetric()), geoRadiusParam), converter)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().georadius(key, - within.getCenter().getX(), within.getCenter().getY(), within.getRadius().getValue(), - JedisConverters.toGeoUnit(within.getRadius().getMetric()), geoRadiusParam), converter)); - return null; - } - - return converter.convert(connection.getJedis().georadius(key, within.getCenter().getX(), - within.getCenter().getY(), within.getRadius().getValue(), - JedisConverters.toGeoUnit(within.getRadius().getMetric()), geoRadiusParam)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + JedisConverters.toGeoUnit(within.getRadius().getMetric()), geoRadiusParam) + .get(converter); } /* @@ -350,22 +224,8 @@ class JedisGeoCommands implements RedisGeoCommands { Converter, GeoResults>> converter = JedisConverters .geoRadiusResponseToGeoResultsConverter(radius.getMetric()); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult( - connection.getRequiredPipeline().georadiusByMember(key, member, radius.getValue(), geoUnit), converter)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult( - connection.getRequiredTransaction().georadiusByMember(key, member, radius.getValue(), geoUnit), converter)); - return null; - } - - return converter.convert(connection.getJedis().georadiusByMember(key, member, radius.getValue(), geoUnit)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::georadiusByMember, MultiKeyPipelineBase::georadiusByMember, key, + member, radius.getValue(), geoUnit).get(converter); } /* @@ -386,23 +246,8 @@ class JedisGeoCommands implements RedisGeoCommands { .geoRadiusResponseToGeoResultsConverter(radius.getMetric()); redis.clients.jedis.params.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(args); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult( - connection.getRequiredPipeline().georadiusByMember(key, member, radius.getValue(), geoUnit, geoRadiusParam), - converter)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().georadiusByMember(key, member, - radius.getValue(), geoUnit, geoRadiusParam), converter)); - return null; - } - return converter - .convert(connection.getJedis().georadiusByMember(key, member, radius.getValue(), geoUnit, geoRadiusParam)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::georadiusByMember, MultiKeyPipelineBase::georadiusByMember, key, + member, radius.getValue(), geoUnit, geoRadiusParam).get(converter); } /* @@ -413,24 +258,4 @@ class JedisGeoCommands implements RedisGeoCommands { public Long geoRemove(byte[] key, byte[]... members) { return connection.zSetCommands().zRem(key, members); } - - 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); - } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java index cd88ab372..57729efbc 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java @@ -15,6 +15,8 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; +import redis.clients.jedis.MultiKeyPipelineBase; import redis.clients.jedis.ScanParams; import redis.clients.jedis.ScanResult; @@ -55,21 +57,8 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(field, "Field must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hset(key, field, value), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hset(key, field, value), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().hset(key, field, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::hset, MultiKeyPipelineBase::hset, key, field, value) + .get(JedisConverters.longToBoolean()); } /* @@ -83,21 +72,8 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(field, "Field must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hsetnx(key, field, value), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hsetnx(key, field, value), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().hsetnx(key, field, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::hsetnx, MultiKeyPipelineBase::hsetnx, key, field, value) + .get(JedisConverters.longToBoolean()); } /* @@ -110,19 +86,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(fields, "Fields must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hdel(key, fields))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hdel(key, fields))); - return null; - } - return connection.getJedis().hdel(key, fields); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hdel, MultiKeyPipelineBase::hdel, key, fields); } /* @@ -135,19 +99,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(field, "Fields must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hexists(key, field))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hexists(key, field))); - return null; - } - return connection.getJedis().hexists(key, field); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hexists, MultiKeyPipelineBase::hexists, key, field); } /* @@ -160,19 +112,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(field, "Field must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hget(key, field))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hget(key, field))); - return null; - } - return connection.getJedis().hget(key, field); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hget, MultiKeyPipelineBase::hget, key, field); } /* @@ -184,19 +124,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hgetAll(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hgetAll(key))); - return null; - } - return connection.getJedis().hgetAll(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hgetAll, MultiKeyPipelineBase::hgetAll, key); } /* @@ -209,19 +137,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(field, "Field must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hincrBy(key, field, delta))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hincrBy(key, field, delta))); - return null; - } - return connection.getJedis().hincrBy(key, field, delta); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hincrBy, MultiKeyPipelineBase::hincrBy, key, field, delta); } /* @@ -234,19 +150,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(field, "Field must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hincrByFloat(key, field, delta))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hincrByFloat(key, field, delta))); - return null; - } - return connection.getJedis().hincrByFloat(key, field, delta); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hincrByFloat, MultiKeyPipelineBase::hincrByFloat, key, field, delta); } /* @@ -258,19 +162,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hkeys(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hkeys(key))); - return null; - } - return connection.getJedis().hkeys(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hkeys, MultiKeyPipelineBase::hkeys, key); } /* @@ -282,19 +174,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hlen(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hlen(key))); - return null; - } - return connection.getJedis().hlen(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hlen, MultiKeyPipelineBase::hlen, key); } /* @@ -307,19 +187,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(fields, "Fields must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hmget(key, fields))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hmget(key, fields))); - return null; - } - return connection.getJedis().hmget(key, fields); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hmget, MultiKeyPipelineBase::hmget, key, fields); } /* @@ -332,19 +200,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(hashes, "Hashes must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().hmset(key, hashes))); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().hmset(key, hashes))); - return; - } - connection.getJedis().hmset(key, hashes); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::hmset, MultiKeyPipelineBase::hmset, key, hashes); } /* @@ -356,19 +212,7 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().hvals(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().hvals(key))); - return null; - } - return connection.getJedis().hvals(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::hvals, MultiKeyPipelineBase::hvals, key); } /* @@ -426,26 +270,14 @@ class JedisHashCommands implements RedisHashCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(field, "Field must not be null!"); - return Long.class.cast(connection.execute("HSTRLEN", key, field)); + return connection.invoke().just(BinaryJedis::hstrlen, MultiKeyPipelineBase::hstrlen, key, field); } 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); - } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHyperLogLogCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHyperLogLogCommands.java index c8b32444b..0bed1d88b 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHyperLogLogCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHyperLogLogCommands.java @@ -15,6 +15,9 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; +import redis.clients.jedis.MultiKeyPipelineBase; + import org.springframework.data.redis.connection.RedisHyperLogLogCommands; import org.springframework.util.Assert; @@ -41,19 +44,7 @@ class JedisHyperLogLogCommands implements RedisHyperLogLogCommands { Assert.notEmpty(values, "PFADD requires at least one non 'null' value."); Assert.noNullElements(values, "Values for PFADD must not contain 'null'."); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().pfadd(key, values))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().pfadd(key, values))); - return null; - } - return connection.getJedis().pfadd(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::pfadd, MultiKeyPipelineBase::pfadd, key, values); } /* @@ -66,19 +57,7 @@ class JedisHyperLogLogCommands implements RedisHyperLogLogCommands { Assert.notEmpty(keys, "PFCOUNT requires at least one non 'null' key."); Assert.noNullElements(keys, "Keys for PFCOUNT must not contain 'null'."); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().pfcount(keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().pfcount(keys))); - return null; - } - return connection.getJedis().pfcount(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::pfcount, MultiKeyPipelineBase::pfcount, keys); } /* @@ -92,39 +71,7 @@ class JedisHyperLogLogCommands implements RedisHyperLogLogCommands { Assert.notNull(sourceKeys, "Source keys must not be null"); Assert.noNullElements(sourceKeys, "Keys for PFMERGE must not contain 'null'."); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().pfmerge(destinationKey, sourceKeys))); - return; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().pfmerge(destinationKey, sourceKeys))); - return; - } - connection.getJedis().pfmerge(destinationKey, sourceKeys); - } 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); + connection.invoke().just(BinaryJedis::pfmerge, MultiKeyPipelineBase::pfmerge, destinationKey, sourceKeys); } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java new file mode 100644 index 000000000..1eb4f98b9 --- /dev/null +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java @@ -0,0 +1,1029 @@ +/* + * Copyright 2021 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 + * + * https://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 redis.clients.jedis.Jedis; +import redis.clients.jedis.MultiKeyPipelineBase; +import redis.clients.jedis.Response; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * Utility for functional invocation of Jedis methods. Typically used to express the method call as method reference and + * passing method arguments through one of the {@code just} or {@code from} methods. + *

+ * {@code just} methods record the method call and evaluate the method result immediately. {@code from} methods allows + * composing a functional pipeline to transform the result using a {@link Converter}. + *

+ * Usage example: + * + *

+ * JedisInvoker invoker = …;
+ *
+ * Long result = invoker.just(BinaryJedisCommands::geoadd, RedisPipeline::geoadd, key, point.getX(), point.getY(), member);
+ *
+ * List<byte[]> result = invoker.from(BinaryJedisCommands::geohash, RedisPipeline::geohash, key, members)
+ * 				.get(JedisConverters.bytesListToStringListConverter());
+ * 
+ *

+ * The actual translation from {@link Response} is delegated to {@link Synchronizer} which can either await completion + * or record the response along {@link Converter} for further processing. + * + * @author Mark Paluch + * @author Christoph Strobl + * @since 2.5 + */ +class JedisInvoker { + + private final Synchronizer synchronizer; + + JedisInvoker(Synchronizer synchronizer) { + this.synchronizer = synchronizer; + } + + /** + * Returns a {@link Converter} that always returns its input argument. + * + * @param the type of the input and output objects to the function + * @return a function that always returns its input argument + */ + static Converter identityConverter() { + return t -> t; + } + + /** + * Invoke the {@link ConnectionFunction0} and return its result. + * + * @param function must not be {@literal null}. + */ + @Nullable + R just(ConnectionFunction0 function) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + + return synchronizer.invoke(function::apply, it -> { + throw new UnsupportedOperationException("Operation not supported in pipelining/transaction mode"); + }, identityConverter(), () -> null); + } + + /** + * Invoke the {@link ConnectionFunction0} and return its result. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + */ + @Nullable + R just(ConnectionFunction0 function, PipelineFunction0 pipelineFunction) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return synchronizer.invoke(function::apply, pipelineFunction::apply, identityConverter(), () -> null); + } + + /** + * Invoke the {@link ConnectionFunction1} and return its result. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + */ + @Nullable + R just(ConnectionFunction1 function, PipelineFunction1 pipelineFunction, T1 t1) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return synchronizer.invoke(it -> function.apply(it, t1), it -> pipelineFunction.apply(it, t1)); + } + + /** + * Invoke the {@link ConnectionFunction2} and return its result. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + */ + @Nullable + R just(ConnectionFunction2 function, PipelineFunction2 pipelineFunction, T1 t1, + T2 t2) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return synchronizer.invoke(it -> function.apply(it, t1, t2), it -> pipelineFunction.apply(it, t1, t2)); + } + + /** + * Invoke the {@link ConnectionFunction3} and return its result. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + */ + @Nullable + R just(ConnectionFunction3 function, PipelineFunction3 pipelineFunction, + T1 t1, T2 t2, T3 t3) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return synchronizer.invoke(it -> function.apply(it, t1, t2, t3), it -> pipelineFunction.apply(it, t1, t2, t3)); + } + + /** + * Invoke the {@link ConnectionFunction4} and return its result. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + */ + @Nullable + R just(ConnectionFunction4 function, + PipelineFunction4 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return synchronizer.invoke(it -> function.apply(it, t1, t2, t3, t4), + it -> pipelineFunction.apply(it, t1, t2, t3, t4)); + } + + /** + * Invoke the {@link ConnectionFunction5} and return its result. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + */ + @Nullable + R just(ConnectionFunction5 function, + PipelineFunction5 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return synchronizer.invoke(it -> function.apply(it, t1, t2, t3, t4, t5), + it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5)); + } + + /** + * Invoke the {@link ConnectionFunction5} and return its result. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + * @param t6 sixth argument. + */ + @Nullable + R just(ConnectionFunction6 function, + PipelineFunction6 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return synchronizer.invoke(it -> function.apply(it, t1, t2, t3, t4, t5, t6), + it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5, t6)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction0} and return a {@link SingleInvocationSpec} for + * further composition. + * + * @param function must not be {@literal null}. + */ + SingleInvocationSpec from(ConnectionFunction0 function) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + + return from(function, connection -> { + throw new UnsupportedOperationException("Operation not supported in pipelining/transaction mode"); + }); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction0} and return a {@link SingleInvocationSpec} for + * further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + */ + SingleInvocationSpec from(ConnectionFunction0 function, PipelineFunction0 pipelineFunction) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return new DefaultSingleInvocationSpec<>(function::apply, pipelineFunction::apply, synchronizer); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction1} and return a {@link SingleInvocationSpec} for + * further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + */ + SingleInvocationSpec from(ConnectionFunction1 function, PipelineFunction1 pipelineFunction, + T1 t1) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return from(it -> function.apply(it, t1), it -> pipelineFunction.apply(it, t1)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction2} and return a {@link SingleInvocationSpec} for + * further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + */ + SingleInvocationSpec from(ConnectionFunction2 function, + PipelineFunction2 pipelineFunction, T1 t1, T2 t2) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return from(it -> function.apply(it, t1, t2), it -> pipelineFunction.apply(it, t1, t2)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction3} and return a {@link SingleInvocationSpec} for + * further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + */ + SingleInvocationSpec from(ConnectionFunction3 function, + PipelineFunction3 pipelineFunction, T1 t1, T2 t2, T3 t3) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return from(it -> function.apply(it, t1, t2, t3), it -> pipelineFunction.apply(it, t1, t2, t3)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction4} and return a {@link SingleInvocationSpec} for + * further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + */ + SingleInvocationSpec from(ConnectionFunction4 function, + PipelineFunction4 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return from(it -> function.apply(it, t1, t2, t3, t4), it -> pipelineFunction.apply(it, t1, t2, t3, t4)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction5} and return a {@link SingleInvocationSpec} for + * further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + */ + SingleInvocationSpec from(ConnectionFunction5 function, + PipelineFunction5 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return from(it -> function.apply(it, t1, t2, t3, t4, t5), it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction6} and return a {@link SingleInvocationSpec} for + * further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + * @param t6 sixth argument. + */ + SingleInvocationSpec from(ConnectionFunction6 function, + PipelineFunction6 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return from(it -> function.apply(it, t1, t2, t3, t4, t5, t6), + it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5, t6)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction0} that returns a {@link Collection}-like result + * and return a {@link ManyInvocationSpec} for further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + */ + , E> ManyInvocationSpec fromMany(ConnectionFunction0 function, + PipelineFunction0 pipelineFunction) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return new DefaultManyInvocationSpec<>((Function) function::apply, pipelineFunction::apply, synchronizer); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction1} that returns a {@link Collection}-like result + * and return a {@link ManyInvocationSpec} for further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + */ + , E, T1> ManyInvocationSpec fromMany(ConnectionFunction1 function, + PipelineFunction1 pipelineFunction, T1 t1) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return fromMany(it -> function.apply(it, t1), it -> pipelineFunction.apply(it, t1)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction2} that returns a {@link Collection}-like result + * and return a {@link ManyInvocationSpec} for further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + */ + , E, T1, T2> ManyInvocationSpec fromMany(ConnectionFunction2 function, + PipelineFunction2 pipelineFunction, T1 t1, T2 t2) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return fromMany(it -> function.apply(it, t1, t2), it -> pipelineFunction.apply(it, t1, t2)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction3} that returns a {@link Collection}-like result + * and return a {@link ManyInvocationSpec} for further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + */ + , E, T1, T2, T3> ManyInvocationSpec fromMany(ConnectionFunction3 function, + PipelineFunction3 pipelineFunction, T1 t1, T2 t2, T3 t3) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return fromMany(it -> function.apply(it, t1, t2, t3), it -> pipelineFunction.apply(it, t1, t2, t3)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction4} that returns a {@link Collection}-like result + * and return a {@link ManyInvocationSpec} for further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + */ + , E, T1, T2, T3, T4> ManyInvocationSpec fromMany( + ConnectionFunction4 function, PipelineFunction4 pipelineFunction, T1 t1, + T2 t2, T3 t3, T4 t4) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return fromMany(it -> function.apply(it, t1, t2, t3, t4), it -> pipelineFunction.apply(it, t1, t2, t3, t4)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction5} that returns a {@link Collection}-like result + * and return a {@link ManyInvocationSpec} for further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + */ + , E, T1, T2, T3, T4, T5> ManyInvocationSpec fromMany( + ConnectionFunction5 function, PipelineFunction5 pipelineFunction, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return fromMany(it -> function.apply(it, t1, t2, t3, t4, t5), it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5)); + } + + /** + * Compose a invocation pipeline from the {@link ConnectionFunction6} that returns a {@link Collection}-like result + * and return a {@link ManyInvocationSpec} for further composition. + * + * @param function must not be {@literal null}. + * @param pipelineFunction must not be {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + * @param t6 sixth argument. + */ + , E, T1, T2, T3, T4, T5, T6> ManyInvocationSpec fromMany( + ConnectionFunction6 function, + PipelineFunction6 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { + + Assert.notNull(function, "ConnectionFunction must not be null!"); + Assert.notNull(pipelineFunction, "PipelineFunction must not be null!"); + + return fromMany(it -> function.apply(it, t1, t2, t3, t4, t5, t6), + it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5, t6)); + } + + /** + * Represents an element in the invocation pipleline allowing consuming the result by applying a {@link Converter}. + * + * @param + */ + interface SingleInvocationSpec { + + /** + * Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying + * {@link Converter}. + * + * @param converter must not be {@literal null}. + * @param target type. + * @return the converted result, can be {@literal null}. + */ + @Nullable + T get(Converter converter); + + /** + * Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying + * {@link Converter} or return the {@literal nullDefault} value if not present. + * + * @param converter must not be {@literal null}. + * @param nullDefault can be {@literal null}. + * @param target type. + * @return the converted result, can be {@literal null}. + */ + @Nullable + default T orElse(Converter converter, @Nullable T nullDefault) { + return getOrElse(converter, () -> nullDefault); + } + + /** + * Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying + * {@link Converter} or return the {@literal nullDefault} value if not present. + * + * @param converter must not be {@literal null}. + * @param nullDefault must not be {@literal null}. + * @param target type. + * @return the converted result, can be {@literal null}. + */ + @Nullable + T getOrElse(Converter converter, Supplier nullDefault); + } + + /** + * Represents an element in the invocation pipleline for methods returning {@link Collection}-like results allowing + * consuming the result by applying a {@link Converter}. + * + * @param + */ + interface ManyInvocationSpec { + + /** + * Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result. + * + * @return the result as {@link List}. + */ + default List toList() { + return toList(identityConverter()); + } + + /** + * Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying + * {@link Converter}. + * + * @param converter must not be {@literal null}. + * @param target type. + * @return the converted {@link List}. + */ + List toList(Converter converter); + + /** + * Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result. + * + * @return the result as {@link Set}. + */ + default Set toSet() { + return toSet(identityConverter()); + } + + /** + * Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying + * {@link Converter}. + * + * @param converter must not be {@literal null}. + * @param target type. + * @return the converted {@link Set}. + */ + Set toSet(Converter converter); + } + + /** + * A function accepting {@link Jedis} with 0 arguments. + * + * @param + */ + @FunctionalInterface + interface ConnectionFunction0 { + + /** + * Apply this function to the arguments and return a response. + * + * @param connection the connection in use. Never {@literal null}. + */ + R apply(Jedis connection); + } + + /** + * A function accepting {@link Jedis} with 1 argument. + * + * @param + * @param + */ + @FunctionalInterface + interface ConnectionFunction1 { + + /** + * Apply this function to the arguments and return a response. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + */ + R apply(Jedis connection, T1 t1); + } + + /** + * A function accepting {@link Jedis} with 2 arguments. + * + * @param + * @param + * @param + */ + @FunctionalInterface + interface ConnectionFunction2 { + + /** + * Apply this function to the arguments and return a response. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + */ + R apply(Jedis connection, T1 t1, T2 t2); + } + + /** + * A function accepting {@link Jedis} with 3 arguments. + * + * @param + * @param + * @param + * @param + */ + @FunctionalInterface + interface ConnectionFunction3 { + + /** + * Apply this function to the arguments and return a response. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + */ + R apply(Jedis connection, T1 t1, T2 t2, T3 t3); + } + + /** + * A function accepting {@link Jedis} with 4 arguments. + * + * @param + * @param + * @param + * @param + * @param + */ + @FunctionalInterface + interface ConnectionFunction4 { + + /** + * Apply this function to the arguments and return a response. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + */ + R apply(Jedis connection, T1 t1, T2 t2, T3 t3, T4 t4); + } + + /** + * A function accepting {@link Jedis} with 5 arguments. + * + * @param + * @param + * @param + * @param + * @param + * @param + */ + @FunctionalInterface + interface ConnectionFunction5 { + + /** + * Apply this function to the arguments and return a response. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + */ + R apply(Jedis connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5); + } + + /** + * A function accepting {@link Jedis} with 6 arguments. + * + * @param + * @param + * @param + * @param + * @param + * @param + * @param + */ + @FunctionalInterface + interface ConnectionFunction6 { + + /** + * Apply this function to the arguments and return a response. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + * @param t6 sixth argument. + */ + R apply(Jedis connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6); + } + + /** + * A function accepting {@link MultiKeyPipelineBase} with 0 arguments. + * + * @param + */ + @FunctionalInterface + interface PipelineFunction0 { + + /** + * Apply this function to the arguments and return a {@link Response}. + * + * @param connection the connection in use. Never {@literal null}. + */ + Response apply(MultiKeyPipelineBase connection); + } + + /** + * A function accepting {@link MultiKeyPipelineBase} with 1 argument. + * + * @param + * @param + */ + @FunctionalInterface + interface PipelineFunction1 { + + /** + * Apply this function to the arguments and return a {@link Response}. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + */ + Response apply(MultiKeyPipelineBase connection, T1 t1); + } + + /** + * A function accepting {@link MultiKeyPipelineBase} with 2 arguments. + * + * @param + * @param + * @param + */ + @FunctionalInterface + interface PipelineFunction2 { + + /** + * Apply this function to the arguments and return a {@link Response}. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + */ + Response apply(MultiKeyPipelineBase connection, T1 t1, T2 t2); + } + + /** + * A function accepting {@link MultiKeyPipelineBase} with 3 arguments. + * + * @param + * @param + * @param + * @param + */ + @FunctionalInterface + interface PipelineFunction3 { + + /** + * Apply this function to the arguments and return a {@link Response}. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + */ + Response apply(MultiKeyPipelineBase connection, T1 t1, T2 t2, T3 t3); + } + + /** + * A function accepting {@link MultiKeyPipelineBase} with 4 arguments. + * + * @param + * @param + * @param + * @param + * @param + */ + @FunctionalInterface + interface PipelineFunction4 { + + /** + * Apply this function to the arguments and return a {@link Response}. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + */ + Response apply(MultiKeyPipelineBase connection, T1 t1, T2 t2, T3 t3, T4 t4); + } + + /** + * A function accepting {@link MultiKeyPipelineBase} with 5 arguments. + * + * @param + * @param + * @param + * @param + * @param + * @param + */ + @FunctionalInterface + interface PipelineFunction5 { + + /** + * Apply this function to the arguments and return a {@link Response}. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + */ + Response apply(MultiKeyPipelineBase connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5); + } + + /** + * A function accepting {@link MultiKeyPipelineBase} with 6 arguments. + * + * @param + * @param + * @param + * @param + * @param + * @param + * @param + */ + @FunctionalInterface + interface PipelineFunction6 { + + /** + * Apply this function to the arguments and return a {@link Response}. + * + * @param connection the connection in use. Never {@literal null}. + * @param t1 first argument. + * @param t2 second argument. + * @param t3 third argument. + * @param t4 fourth argument. + * @param t5 fifth argument. + * @param t6 sixth argument. + */ + Response apply(MultiKeyPipelineBase connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6); + } + + static class DefaultSingleInvocationSpec implements SingleInvocationSpec { + + private final Function parentFunction; + private final Function> parentPipelineFunction; + private final Synchronizer synchronizer; + + public DefaultSingleInvocationSpec(Function parentFunction, + Function> parentPipelineFunction, Synchronizer synchronizer) { + this.parentFunction = parentFunction; + this.parentPipelineFunction = parentPipelineFunction; + this.synchronizer = synchronizer; + } + + @Override + public T get(Converter converter) { + + Assert.notNull(converter, "Converter must not be null"); + + return synchronizer.invoke(parentFunction, parentPipelineFunction, converter, () -> null); + } + + @Nullable + @Override + public T getOrElse(Converter converter, Supplier nullDefault) { + + Assert.notNull(converter, "Converter must not be null!"); + + return synchronizer.invoke(parentFunction, parentPipelineFunction, converter, nullDefault); + } + } + + static class DefaultManyInvocationSpec implements ManyInvocationSpec { + + private final Function> parentFunction; + private final Function>> parentPipelineFunction; + private final Synchronizer synchronizer; + + public DefaultManyInvocationSpec(Function> parentFunction, + Function>> parentPipelineFunction, + Synchronizer synchronizer) { + + this.parentFunction = (Function) parentFunction; + this.parentPipelineFunction = (Function) parentPipelineFunction; + this.synchronizer = synchronizer; + } + + @Override + public List toList(Converter converter) { + + Assert.notNull(converter, "Converter must not be null!"); + + return synchronizer.invoke(parentFunction, parentPipelineFunction, source -> { + + if (source.isEmpty()) { + return Collections.emptyList(); + } + + List result = new ArrayList<>(source.size()); + + for (S s : source) { + result.add(converter.convert(s)); + } + + return result; + }, Collections::emptyList); + } + + @Override + public Set toSet(Converter converter) { + + Assert.notNull(converter, "Converter must not be null!"); + + return synchronizer.invoke(parentFunction, parentPipelineFunction, source -> { + + if (source.isEmpty()) { + return Collections.emptySet(); + } + + Set result = new LinkedHashSet<>(source.size()); + + for (S s : source) { + result.add(converter.convert(s)); + } + + return result; + }, Collections::emptySet); + } + } + + /** + * Interface to define a synchronization function to evaluate the actual call. + */ + @FunctionalInterface + interface Synchronizer { + + @Nullable + @SuppressWarnings({ "unchecked", "rawtypes" }) + default T invoke(Function callFunction, + Function> pipelineFunction) { + return (T) doInvoke((Function) callFunction, (Function) pipelineFunction, identityConverter(), () -> null); + } + + @Nullable + @SuppressWarnings({ "unchecked", "rawtypes" }) + default T invoke(Function callFunction, + Function> pipelineFunction, Converter converter, + Supplier nullDefault) { + + return (T) doInvoke((Function) callFunction, (Function) pipelineFunction, (Converter) converter, + (Supplier) nullDefault); + } + + @Nullable + Object doInvoke(Function callFunction, + Function> pipelineFunction, Converter converter, + Supplier nullDefault); + } +} diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java index cf7a0b6fe..bcaa0cb3d 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java @@ -15,6 +15,8 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; +import redis.clients.jedis.MultiKeyPipelineBase; import redis.clients.jedis.ScanParams; import redis.clients.jedis.SortingParams; @@ -58,19 +60,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().exists(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().exists(key))); - return null; - } - return connection.getJedis().exists(key); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::exists, MultiKeyPipelineBase::exists, key); } /* @@ -84,19 +74,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(keys, "Keys must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().exists(keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().exists(keys))); - return null; - } - return connection.getJedis().exists(keys); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::exists, MultiKeyPipelineBase::exists, keys); } /* @@ -109,19 +87,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(keys, "Keys must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().del(keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().del(keys))); - return null; - } - return connection.getJedis().del(keys); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::del, MultiKeyPipelineBase::del, keys); } /* @@ -134,7 +100,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(keys, "Keys must not be null!"); - return Long.class.cast(connection.execute("UNLINK", keys)); + return connection.invoke().just(BinaryJedis::unlink, MultiKeyPipelineBase::unlink, keys); } /* @@ -146,21 +112,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline( - connection.newJedisResult(connection.getRequiredPipeline().type(key), JedisConverters.stringToDataType())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().type(key), - JedisConverters.stringToDataType())); - return null; - } - return JedisConverters.toDataType(connection.getJedis().type(key)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::type, MultiKeyPipelineBase::type, key) + .get(JedisConverters.stringToDataType()); } /* @@ -173,7 +126,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(keys, "Keys must not be null!"); - return Long.class.cast(connection.execute("TOUCH", keys)); + return connection.invoke().just(BinaryJedis::touch, MultiKeyPipelineBase::touch, keys); } /* @@ -185,19 +138,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(pattern, "Pattern must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().keys(pattern))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().keys(pattern))); - return null; - } - return connection.getJedis().keys(pattern); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::keys, MultiKeyPipelineBase::keys, pattern); } /* @@ -234,7 +175,9 @@ class JedisKeyCommands implements RedisKeyCommands { protected void doClose() { JedisKeyCommands.this.connection.close(); - }; + } + + ; }.open(); } @@ -245,20 +188,7 @@ class JedisKeyCommands implements RedisKeyCommands { */ @Override public byte[] randomKey() { - - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().randomKeyBinary())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().randomKeyBinary())); - return null; - } - return connection.getJedis().randomBinaryKey(); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::randomBinaryKey, MultiKeyPipelineBase::randomKeyBinary); } /* @@ -271,19 +201,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(sourceKey, "Source key must not be null!"); Assert.notNull(targetKey, "Target key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().rename(sourceKey, targetKey))); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().rename(sourceKey, targetKey))); - return; - } - connection.getJedis().rename(sourceKey, targetKey); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::rename, MultiKeyPipelineBase::rename, sourceKey, targetKey); } /* @@ -296,21 +214,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(sourceKey, "Source key must not be null!"); Assert.notNull(targetKey, "Target key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().renamenx(sourceKey, targetKey), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().renamenx(sourceKey, targetKey), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().renamenx(sourceKey, targetKey)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::renamenx, MultiKeyPipelineBase::renamenx, sourceKey, targetKey) + .get(JedisConverters.longToBoolean()); } /* @@ -326,21 +231,8 @@ class JedisKeyCommands implements RedisKeyCommands { return pExpire(key, TimeUnit.SECONDS.toMillis(seconds)); } - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().expire(key, (int) seconds), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().expire(key, (int) seconds), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().expire(key, (int) seconds)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::expire, MultiKeyPipelineBase::expire, key, (int) seconds) + .get(JedisConverters.longToBoolean()); } /* @@ -352,21 +244,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().pexpire(key, millis), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().pexpire(key, millis), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().pexpire(key, millis)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::pexpire, MultiKeyPipelineBase::pexpire, key, millis) + .get(JedisConverters.longToBoolean()); } /* @@ -378,21 +257,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().expireAt(key, unixTime), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().expireAt(key, unixTime), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().expireAt(key, unixTime)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::expireAt, MultiKeyPipelineBase::expireAt, key, unixTime) + .get(JedisConverters.longToBoolean()); } /* @@ -404,21 +270,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().pexpireAt(key, unixTimeInMillis), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().pexpireAt(key, unixTimeInMillis), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().pexpireAt(key, unixTimeInMillis)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::pexpireAt, MultiKeyPipelineBase::pexpireAt, key, unixTimeInMillis) + .get(JedisConverters.longToBoolean()); } /* @@ -430,21 +283,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline( - connection.newJedisResult(connection.getRequiredPipeline().persist(key), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().persist(key), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().persist(key)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::persist, MultiKeyPipelineBase::persist, key) + .get(JedisConverters.longToBoolean()); } /* @@ -456,21 +296,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().move(key, dbIndex), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().move(key, dbIndex), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().move(key, dbIndex)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::move, MultiKeyPipelineBase::move, key, dbIndex) + .get(JedisConverters.longToBoolean()); } /* @@ -482,20 +309,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().ttl(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().ttl(key))); - return null; - } - - return connection.getJedis().ttl(key); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::ttl, MultiKeyPipelineBase::ttl, key); } /* @@ -507,22 +321,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().ttl(key), - Converters.secondsToTimeUnit(timeUnit))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().ttl(key), - Converters.secondsToTimeUnit(timeUnit))); - return null; - } - - return Converters.secondsToTimeUnit(connection.getJedis().ttl(key), timeUnit); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::ttl, MultiKeyPipelineBase::ttl, key) + .get(Converters.secondsToTimeUnit(timeUnit)); } /* @@ -534,20 +334,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().pttl(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().pttl(key))); - return null; - } - - return connection.getJedis().pttl(key); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::pttl, MultiKeyPipelineBase::pttl, key); } /* @@ -559,22 +346,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().pttl(key), - Converters.millisecondsToTimeUnit(timeUnit))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().pttl(key), - Converters.millisecondsToTimeUnit(timeUnit))); - return null; - } - - return Converters.millisecondsToTimeUnit(connection.getJedis().pttl(key), timeUnit); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::pttl, MultiKeyPipelineBase::pttl, key) + .get(Converters.millisecondsToTimeUnit(timeUnit)); } /* @@ -588,29 +361,11 @@ class JedisKeyCommands implements RedisKeyCommands { SortingParams sortParams = JedisConverters.toSortingParams(params); - try { - if (isPipelined()) { - if (sortParams != null) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sort(key, sortParams))); - } else { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sort(key))); - } - - return null; - } - if (isQueueing()) { - if (sortParams != null) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sort(key, sortParams))); - } else { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sort(key))); - } - - return null; - } - return (sortParams != null ? connection.getJedis().sort(key, sortParams) : connection.getJedis().sort(key)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); + if (sortParams != null) { + return connection.invoke().just(BinaryJedis::sort, MultiKeyPipelineBase::sort, key, sortParams); } + + return connection.invoke().just(BinaryJedis::sort, MultiKeyPipelineBase::sort, key); } /* @@ -624,30 +379,11 @@ class JedisKeyCommands implements RedisKeyCommands { SortingParams sortParams = JedisConverters.toSortingParams(params); - try { - if (isPipelined()) { - if (sortParams != null) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sort(key, sortParams, storeKey))); - } else { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sort(key, storeKey))); - } - - return null; - } - if (isQueueing()) { - if (sortParams != null) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sort(key, sortParams, storeKey))); - } else { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sort(key, storeKey))); - } - - return null; - } - return (sortParams != null ? connection.getJedis().sort(key, sortParams, storeKey) - : connection.getJedis().sort(key, storeKey)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); + if (sortParams != null) { + return connection.invoke().just(BinaryJedis::sort, MultiKeyPipelineBase::sort, key, sortParams, storeKey); } + + return connection.invoke().just(BinaryJedis::sort, MultiKeyPipelineBase::sort, key, storeKey); } /* @@ -659,19 +395,7 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().dump(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().dump(key))); - return null; - } - return connection.getJedis().dump(key); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::dump, MultiKeyPipelineBase::dump, key); } /* @@ -686,30 +410,17 @@ class JedisKeyCommands implements RedisKeyCommands { if (replace) { - this.connection.execute("RESTORE", new byte[][] { key, JedisConverters.toBytes(ttlInMillis), serializedValue, - JedisConverters.toBytes("REPLACE") }); + connection.invokeStatus().just(BinaryJedis::restoreReplace, MultiKeyPipelineBase::restoreReplace, key, + (int) ttlInMillis, serializedValue); return; } if (ttlInMillis > Integer.MAX_VALUE) { throw new IllegalArgumentException("TtlInMillis must be less than Integer.MAX_VALUE for restore in Jedis."); } - try { - if (isPipelined()) { - pipeline(connection - .newStatusResult(connection.getRequiredPipeline().restore(key, (int) ttlInMillis, serializedValue))); - return; - } - if (isQueueing()) { - transaction(connection - .newStatusResult(connection.getRequiredTransaction().restore(key, (int) ttlInMillis, serializedValue))); - return; - } - connection.getJedis().restore(key, (int) ttlInMillis, serializedValue); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::restore, MultiKeyPipelineBase::restore, key, (int) ttlInMillis, + serializedValue); } /* @@ -722,21 +433,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().objectEncoding(key), - JedisConverters::toEncoding, () -> RedisValueEncoding.VACANT)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().objectEncoding(key), - JedisConverters::toEncoding, () -> RedisValueEncoding.VACANT)); - return null; - } - return JedisConverters.toEncoding(connection.getJedis().objectEncoding(key)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::objectEncoding, MultiKeyPipelineBase::objectEncoding, key) + .getOrElse(JedisConverters::toEncoding, () -> RedisValueEncoding.VACANT); } /* @@ -749,22 +447,8 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().objectIdletime(key), - Converters::secondsToDuration)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().objectIdletime(key), - Converters::secondsToDuration)); - return null; - } - - return Converters.secondsToDuration(connection.getJedis().objectIdletime(key)); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::objectIdletime, MultiKeyPipelineBase::objectIdletime, key) + .get(Converters::secondsToDuration); } /* @@ -777,35 +461,15 @@ class JedisKeyCommands implements RedisKeyCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().objectRefcount(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().objectRefcount(key))); - return null; - } - - return connection.getJedis().objectRefcount(key); - } catch (Exception ex) { - throw connection.convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::objectRefcount, MultiKeyPipelineBase::objectRefcount, key); } 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); - } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java index b0cc36d51..fcf540e67 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java @@ -15,9 +15,10 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; +import redis.clients.jedis.MultiKeyPipelineBase; import redis.clients.jedis.Protocol; -import java.util.ArrayList; import java.util.List; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -47,19 +48,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().rpush(key, values))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().rpush(key, values))); - return null; - } - return connection.getJedis().rpush(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::rpush, MultiKeyPipelineBase::rpush, key, values); } /* @@ -86,19 +75,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(values, "Values must not be null!"); Assert.noNullElements(values, "Values must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().lpush(key, values))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().lpush(key, values))); - return null; - } - return connection.getJedis().lpush(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::lpush, MultiKeyPipelineBase::lpush, key, values); } /* @@ -111,19 +88,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().rpushx(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().rpushx(key, value))); - return null; - } - return connection.getJedis().rpushx(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::rpushx, MultiKeyPipelineBase::rpushx, key, value); } /* @@ -136,19 +101,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().lpushx(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().lpushx(key, value))); - return null; - } - return connection.getJedis().lpushx(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::lpushx, MultiKeyPipelineBase::lpushx, key, value); } /* @@ -160,19 +113,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().llen(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().llen(key))); - return null; - } - return connection.getJedis().llen(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::llen, MultiKeyPipelineBase::llen, key); } /* @@ -184,19 +125,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().lrange(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().lrange(key, start, end))); - return null; - } - return connection.getJedis().lrange(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::lrange, MultiKeyPipelineBase::lrange, key, start, end); } /* @@ -208,19 +137,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().ltrim(key, start, end))); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().ltrim(key, start, end))); - return; - } - connection.getJedis().ltrim(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::ltrim, MultiKeyPipelineBase::ltrim, key, start, end); } /* @@ -232,19 +149,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().lindex(key, index))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().lindex(key, index))); - return null; - } - return connection.getJedis().lindex(key, index); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::lindex, MultiKeyPipelineBase::lindex, key, index); } /* @@ -256,21 +161,8 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult( - connection.getRequiredPipeline().linsert(key, JedisConverters.toListPosition(where), pivot, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult( - connection.getRequiredTransaction().linsert(key, JedisConverters.toListPosition(where), pivot, value))); - return null; - } - return connection.getJedis().linsert(key, JedisConverters.toListPosition(where), pivot, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::linsert, MultiKeyPipelineBase::linsert, key, + JedisConverters.toListPosition(where), pivot, value); } /* @@ -283,19 +175,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().lset(key, index, value))); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().lset(key, index, value))); - return; - } - connection.getJedis().lset(key, index, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::lset, MultiKeyPipelineBase::lset, key, index, value); } /* @@ -308,19 +188,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().lrem(key, count, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().lrem(key, count, value))); - return null; - } - return connection.getJedis().lrem(key, count, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::lrem, MultiKeyPipelineBase::lrem, key, count, value); } /* @@ -332,19 +200,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().lpop(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().lpop(key))); - return null; - } - return connection.getJedis().lpop(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::lpop, MultiKeyPipelineBase::lpop, key); } /* @@ -356,20 +212,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().rpop(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().rpop(key))); - return null; - } - return connection.getJedis().rpop(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - + return connection.invoke().just(BinaryJedis::rpop, MultiKeyPipelineBase::rpop, key); } /* @@ -382,19 +225,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(keys, "Key must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().blpop(bXPopArgs(timeout, keys)))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().blpop(bXPopArgs(timeout, keys)))); - return null; - } - return connection.getJedis().blpop(timeout, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::blpop, MultiKeyPipelineBase::blpop, bXPopArgs(timeout, keys)); } /* @@ -407,19 +238,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(keys, "Key must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().brpop(bXPopArgs(timeout, keys)))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().brpop(bXPopArgs(timeout, keys)))); - return null; - } - return connection.getJedis().brpop(timeout, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::brpop, MultiKeyPipelineBase::brpop, bXPopArgs(timeout, keys)); } /* @@ -432,19 +251,7 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(srcKey, "Source key must not be null!"); Assert.notNull(dstKey, "Destination key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().rpoplpush(srcKey, dstKey))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().rpoplpush(srcKey, dstKey))); - return null; - } - return connection.getJedis().rpoplpush(srcKey, dstKey); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::rpoplpush, MultiKeyPipelineBase::rpoplpush, srcKey, dstKey); } /* @@ -457,48 +264,16 @@ class JedisListCommands implements RedisListCommands { Assert.notNull(srcKey, "Source key must not be null!"); Assert.notNull(dstKey, "Destination key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().brpoplpush(srcKey, dstKey, timeout))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().brpoplpush(srcKey, dstKey, timeout))); - return null; - } - return connection.getJedis().brpoplpush(srcKey, dstKey, timeout); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::brpoplpush, MultiKeyPipelineBase::brpoplpush, srcKey, dstKey, timeout); } - private byte[][] bXPopArgs(int timeout, byte[]... keys) { + private static byte[][] bXPopArgs(int timeout, byte[]... keys) { - List args = new ArrayList<>(); - for (byte[] arg : keys) { - args.add(arg); - } - args.add(Protocol.toByteArray(timeout)); - return args.toArray(new byte[args.size()][]); + byte[][] args = new byte[keys.length + 1][]; + System.arraycopy(keys, 0, args, 0, keys.length); + + args[args.length - 1] = Protocol.toByteArray(timeout); + return args; } - 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); - } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java index 6ea0d6127..164c749fb 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java @@ -159,7 +159,7 @@ class JedisResult extends FutureResult> { /** * @return a new {@link JedisStatusResult} wrapper for status results with configuration applied from this builder. */ - JedisStatusResult buildStatusResult() { + JedisStatusResult buildStatusResult() { return new JedisStatusResult<>(response, converter); } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptReturnConverter.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptReturnConverter.java index 9c8fc238f..a937cd100 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptReturnConverter.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptReturnConverter.java @@ -22,6 +22,7 @@ import java.util.List; import org.springframework.core.convert.converter.Converter; import org.springframework.data.redis.connection.ReturnType; +import org.springframework.lang.Nullable; /** * Converts the value returned by Jedis script eval to the expected {@link ReturnType} @@ -37,7 +38,7 @@ public class JedisScriptReturnConverter implements Converter { } @SuppressWarnings("unchecked") - public Object convert(Object result) { + public Object convert(@Nullable Object result) { if (result instanceof String) { // evalsha converts byte[] to String. Convert back for consistency return SafeEncoder.encode((String) result); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java index ae1c5f863..ca21da256 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java @@ -15,6 +15,8 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; + import java.util.List; import org.springframework.data.redis.connection.RedisScriptingCommands; @@ -40,15 +42,9 @@ class JedisScriptingCommands implements RedisScriptingCommands { @Override public void scriptFlush() { - if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException(); - } + assertDirectMode(); - try { - connection.getJedis().scriptFlush(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invoke().just(BinaryJedis::scriptFlush); } /* @@ -58,15 +54,9 @@ class JedisScriptingCommands implements RedisScriptingCommands { @Override public void scriptKill() { - if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException(); - } + assertDirectMode(); - try { - connection.getJedis().scriptKill(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invoke().just(BinaryJedis::scriptKill); } /* @@ -77,16 +67,9 @@ class JedisScriptingCommands implements RedisScriptingCommands { public String scriptLoad(byte[] script) { Assert.notNull(script, "Script must not be null!"); + assertDirectMode(); - if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException(); - } - - try { - return JedisConverters.toString(connection.getJedis().scriptLoad(script)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(it -> it.scriptLoad(script)).get(JedisConverters::toString); } /* @@ -98,16 +81,9 @@ class JedisScriptingCommands implements RedisScriptingCommands { Assert.notNull(scriptSha1, "Script digests must not be null!"); Assert.noNullElements(scriptSha1, "Script digests must not contain null elements!"); + assertDirectMode(); - if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException(); - } - - try { - return connection.getJedis().scriptExists(scriptSha1); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(it -> it.scriptExists(scriptSha1)); } /* @@ -119,17 +95,11 @@ class JedisScriptingCommands implements RedisScriptingCommands { public T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { Assert.notNull(script, "Script must not be null!"); + assertDirectMode(); - if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException(); - } - - try { - return (T) new JedisScriptReturnConverter(returnType) - .convert(connection.getJedis().eval(script, JedisConverters.toBytes(numKeys), keysAndArgs)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + JedisScriptReturnConverter converter = new JedisScriptReturnConverter(returnType); + return (T) connection.invoke().from(it -> it.eval(script, JedisConverters.toBytes(numKeys), keysAndArgs)) + .getOrElse(converter, () -> converter.convert(null)); } /* @@ -150,28 +120,17 @@ class JedisScriptingCommands implements RedisScriptingCommands { public T evalSha(byte[] scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { Assert.notNull(scriptSha, "Script digest must not be null!"); + assertDirectMode(); - if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException(); - } + JedisScriptReturnConverter converter = new JedisScriptReturnConverter(returnType); + return (T) connection.invoke().from(it -> it.evalsha(scriptSha, numKeys, keysAndArgs)).getOrElse(converter, + () -> converter.convert(null)); + } - try { - return (T) new JedisScriptReturnConverter(returnType) - .convert(connection.getJedis().evalsha(scriptSha, numKeys, keysAndArgs)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + private void assertDirectMode() { + if (connection.isQueueing() || connection.isPipelined()) { + throw new UnsupportedOperationException("Scripting commands not supported in pipelining/transaction mode"); } } - private boolean isPipelined() { - return connection.isPipelined(); - } - - private boolean isQueueing() { - return connection.isQueueing(); - } - - private RuntimeException convertJedisAccessException(Exception ex) { - return connection.convertJedisAccessException(ex); - } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java index 25f5fb0c4..08e0f2686 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java @@ -15,6 +15,10 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.MultiKeyPipelineBase; + import java.util.List; import java.util.Properties; @@ -46,20 +50,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public void bgReWriteAof() { - - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().bgrewriteaof())); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().bgrewriteaof())); - return; - } - connection.getJedis().bgrewriteaof(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invoke().just(BinaryJedis::bgrewriteaof, MultiKeyPipelineBase::bgrewriteaof); } /* @@ -68,20 +59,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public void bgSave() { - - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().bgsave())); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().bgsave())); - return; - } - connection.getJedis().bgsave(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::bgsave, MultiKeyPipelineBase::bgsave); } /* @@ -90,20 +68,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public Long lastSave() { - - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().lastsave())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().lastsave())); - return null; - } - return connection.getJedis().lastsave(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::lastsave, MultiKeyPipelineBase::lastsave); } /* @@ -112,20 +77,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public void save() { - - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().save())); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().save())); - return; - } - connection.getJedis().save(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::save, MultiKeyPipelineBase::save); } /* @@ -134,20 +86,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public Long dbSize() { - - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().dbSize())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().dbSize())); - return null; - } - return connection.getJedis().dbSize(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::dbSize, MultiKeyPipelineBase::dbSize); } /* @@ -156,20 +95,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public void flushDb() { - - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().flushDB())); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().flushDB())); - return; - } - connection.getJedis().flushDB(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::flushDB, MultiKeyPipelineBase::flushDB); } /* @@ -178,20 +104,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public void flushAll() { - - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().flushAll())); - return; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().flushAll())); - return; - } - connection.getJedis().flushAll(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::flushAll, MultiKeyPipelineBase::flushAll); } /* @@ -200,21 +113,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public Properties info() { - - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().info(), JedisConverters.stringToProps())); - return null; - } - if (isQueueing()) { - transaction( - connection.newJedisResult(connection.getRequiredTransaction().info(), JedisConverters.stringToProps())); - return null; - } - return JedisConverters.toProperties(connection.getJedis().info()); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::info, MultiKeyPipelineBase::info).get(JedisConverters::toProperties); } /* @@ -226,15 +125,8 @@ class JedisServerCommands implements RedisServerCommands { Assert.notNull(section, "Section must not be null!"); - if (isPipelined() || isQueueing()) { - throw new UnsupportedOperationException(); - } - - try { - return JedisConverters.toProperties(connection.getJedis().info(section)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::info, MultiKeyPipelineBase::info, section) + .get(JedisConverters::toProperties); } /* @@ -243,20 +135,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public void shutdown() { - - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().shutdown())); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().shutdown())); - return; - } - connection.getJedis().shutdown(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::shutdown, MultiKeyPipelineBase::shutdown); } /* @@ -283,21 +162,8 @@ class JedisServerCommands implements RedisServerCommands { Assert.notNull(pattern, "Pattern must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().configGet(pattern), - Converters.listToPropertiesConverter())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().configGet(pattern), - Converters.listToPropertiesConverter())); - return null; - } - return Converters.toProperties(connection.getJedis().configGet(pattern)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(Jedis::configGet, MultiKeyPipelineBase::configGet, pattern) + .get(Converters::toProperties); } /* @@ -310,19 +176,7 @@ class JedisServerCommands implements RedisServerCommands { Assert.notNull(param, "Parameter must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().configSet(param, value))); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().configSet(param, value))); - return; - } - connection.getJedis().configSet(param, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(Jedis::configSet, MultiKeyPipelineBase::configSet, param, value); } /* @@ -331,20 +185,7 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public void resetConfigStats() { - - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().configResetStat())); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().configResetStat())); - return; - } - connection.getJedis().configResetStat(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::configResetStat, MultiKeyPipelineBase::configResetStat); } /* @@ -353,21 +194,8 @@ class JedisServerCommands implements RedisServerCommands { */ @Override public Long time() { - - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().time(), JedisConverters.toTimeConverter())); - return null; - } - if (isQueueing()) { - transaction( - connection.newJedisResult(connection.getRequiredTransaction().time(), JedisConverters.toTimeConverter())); - return null; - } - return JedisConverters.toTimeConverter().convert(connection.getJedis().time()); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::time, MultiKeyPipelineBase::time) + .get(JedisConverters.toTimeConverter()); } /* @@ -383,11 +211,7 @@ class JedisServerCommands implements RedisServerCommands { 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); - } + connection.invokeStatus().just(it -> it.clientKill(String.format("%s:%s", host, port))); } /* @@ -403,7 +227,7 @@ class JedisServerCommands implements RedisServerCommands { throw new UnsupportedOperationException("'CLIENT SETNAME' is not suppored in transacton / pipeline mode."); } - connection.getJedis().clientSetname(name); + connection.invokeStatus().just(it -> it.clientSetname(name)); } /* @@ -417,7 +241,7 @@ class JedisServerCommands implements RedisServerCommands { throw new UnsupportedOperationException(); } - return connection.getJedis().clientGetname(); + return connection.invokeStatus().just(Jedis::clientGetname); } /* @@ -430,7 +254,8 @@ class JedisServerCommands implements RedisServerCommands { if (isQueueing() || isPipelined()) { throw new UnsupportedOperationException("'CLIENT LIST' is not supported in in pipeline / multi mode."); } - return JedisConverters.toListOfRedisClientInformation(this.connection.getJedis().clientList()); + + return connection.invokeStatus().from(Jedis::clientList).get(JedisConverters::toListOfRedisClientInformation); } /* @@ -445,11 +270,8 @@ class JedisServerCommands implements RedisServerCommands { 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); - } + + connection.invokeStatus().just(it -> it.slaveof(host, port)); } /* @@ -463,11 +285,7 @@ class JedisServerCommands implements RedisServerCommands { throw new UnsupportedOperationException("'SLAVEOF' cannot be called in pipline / transaction mode."); } - try { - this.connection.getJedis().slaveofNoOne(); - } catch (Exception e) { - throw convertJedisAccessException(e); - } + connection.invokeStatus().just(BinaryJedis::slaveofNoOne); } /* @@ -491,42 +309,16 @@ class JedisServerCommands implements RedisServerCommands { int timeoutToUse = timeout <= Integer.MAX_VALUE ? (int) timeout : Integer.MAX_VALUE; - try { - if (isPipelined()) { - - pipeline(connection.newJedisResult( - connection.getRequiredPipeline().migrate(target.getHost(), target.getPort(), key, dbIndex, timeoutToUse))); - return; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().migrate(target.getHost(), - target.getPort(), key, dbIndex, timeoutToUse))); - return; - } - connection.getJedis().migrate(target.getHost(), target.getPort(), key, dbIndex, timeoutToUse); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - + connection.invokeStatus().just(BinaryJedis::migrate, MultiKeyPipelineBase::migrate, target.getHost(), + target.getPort(), key, dbIndex, timeoutToUse); } 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); - } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java index a3dc6ad10..6f845145d 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java @@ -15,6 +15,8 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; +import redis.clients.jedis.MultiKeyPipelineBase; import redis.clients.jedis.ScanParams; import java.util.ArrayList; @@ -52,19 +54,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(values, "Values must not be null!"); Assert.noNullElements(values, "Values must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sadd(key, values))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sadd(key, values))); - return null; - } - return connection.getJedis().sadd(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::sadd, MultiKeyPipelineBase::sadd, key, values); } /* @@ -76,19 +66,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().scard(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().scard(key))); - return null; - } - return connection.getJedis().scard(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::scard, MultiKeyPipelineBase::scard, key); } /* @@ -101,19 +79,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(keys, "Keys must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sdiff(keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sdiff(keys))); - return null; - } - return connection.getJedis().sdiff(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::sdiff, MultiKeyPipelineBase::sdiff, keys); } /* @@ -127,19 +93,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(keys, "Source keys must not be null!"); Assert.noNullElements(keys, "Source keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sdiffstore(destKey, keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sdiffstore(destKey, keys))); - return null; - } - return connection.getJedis().sdiffstore(destKey, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::sdiffstore, MultiKeyPipelineBase::sdiffstore, destKey, keys); } /* @@ -152,19 +106,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(keys, "Keys must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sinter(keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sinter(keys))); - return null; - } - return connection.getJedis().sinter(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::sinter, MultiKeyPipelineBase::sinter, keys); } /* @@ -178,19 +120,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(keys, "Source keys must not be null!"); Assert.noNullElements(keys, "Source keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sinterstore(destKey, keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sinterstore(destKey, keys))); - return null; - } - return connection.getJedis().sinterstore(destKey, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::sinterstore, MultiKeyPipelineBase::sinterstore, destKey, keys); } /* @@ -203,19 +133,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sismember(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sismember(key, value))); - return null; - } - return connection.getJedis().sismember(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::sismember, MultiKeyPipelineBase::sismember, key, value); } /* @@ -227,19 +145,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().smembers(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().smembers(key))); - return null; - } - return connection.getJedis().smembers(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::smembers, MultiKeyPipelineBase::smembers, key); } /* @@ -253,21 +159,8 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(destKey, "Destination key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().smove(srcKey, destKey, value), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().smove(srcKey, destKey, value), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().smove(srcKey, destKey, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::smove, MultiKeyPipelineBase::smove, srcKey, destKey, value) + .get(JedisConverters::toBoolean); } /* @@ -279,19 +172,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().spop(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().spop(key))); - return null; - } - return connection.getJedis().spop(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::spop, MultiKeyPipelineBase::spop, key); } /* @@ -303,19 +184,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().spop(key, count), ArrayList::new)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().spop(key, count), ArrayList::new)); - return null; - } - return new ArrayList<>(connection.getJedis().spop(key, count)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::spop, MultiKeyPipelineBase::spop, key, count).get(ArrayList::new); } /* @@ -327,19 +196,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().srandmember(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().srandmember(key))); - return null; - } - return connection.getJedis().srandmember(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::srandmember, MultiKeyPipelineBase::srandmember, key); } /* @@ -355,19 +212,7 @@ class JedisSetCommands implements RedisSetCommands { throw new IllegalArgumentException("Count must be less than Integer.MAX_VALUE for sRandMember in Jedis."); } - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().srandmember(key, (int) count))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().srandmember(key, (int) count))); - return null; - } - return connection.getJedis().srandmember(key, (int) count); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::srandmember, MultiKeyPipelineBase::srandmember, key, (int) count); } /* @@ -381,19 +226,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(values, "Values must not be null!"); Assert.noNullElements(values, "Values must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().srem(key, values))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().srem(key, values))); - return null; - } - return connection.getJedis().srem(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::srem, MultiKeyPipelineBase::srem, key, values); } /* @@ -406,19 +239,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(keys, "Keys must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sunion(keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sunion(keys))); - return null; - } - return connection.getJedis().sunion(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::sunion, MultiKeyPipelineBase::sunion, keys); } /* @@ -432,19 +253,7 @@ class JedisSetCommands implements RedisSetCommands { Assert.notNull(keys, "Source keys must not be null!"); Assert.noNullElements(keys, "Source keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().sunionstore(destKey, keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().sunionstore(destKey, keys))); - return null; - } - return connection.getJedis().sunionstore(destKey, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::sunionstore, MultiKeyPipelineBase::sunionstore, destKey, keys); } /* @@ -493,19 +302,8 @@ class JedisSetCommands implements RedisSetCommands { 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); - } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java index c6c0a48f2..e9bf3ffeb 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java @@ -15,8 +15,9 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; import redis.clients.jedis.BitPosParams; -import redis.clients.jedis.Client; +import redis.clients.jedis.MultiKeyPipelineBase; import redis.clients.jedis.params.SetParams; import java.util.List; @@ -27,7 +28,6 @@ import org.springframework.data.redis.connection.BitFieldSubCommands; import org.springframework.data.redis.connection.RedisStringCommands; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.types.Expiration; -import org.springframework.data.redis.util.ByteUtils; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -54,20 +54,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().get(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().get(key))); - return null; - } - - return connection.getJedis().get(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::get, MultiKeyPipelineBase::get, key); } /* @@ -80,19 +67,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().getSet(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().getSet(key, value))); - return null; - } - return connection.getJedis().getSet(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::getSet, MultiKeyPipelineBase::getSet, key, value); } /* @@ -105,19 +80,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(keys, "Keys must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().mget(keys))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().mget(keys))); - return null; - } - return connection.getJedis().mget(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::mget, MultiKeyPipelineBase::mget, keys); } /* @@ -130,21 +93,8 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().set(key, value), - Converters.stringToBooleanConverter())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().set(key, value), - Converters.stringToBooleanConverter())); - return null; - } - return Converters.stringToBoolean(connection.getJedis().set(key, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::set, MultiKeyPipelineBase::set, key, value) + .get(Converters.stringToBooleanConverter()); } /* @@ -162,25 +112,8 @@ class JedisStringCommands implements RedisStringCommands { SetParams params = JedisConverters.toSetCommandExPxArgument(expiration, JedisConverters.toSetCommandNxXxArgument(option)); - try { - if (isPipelined()) { - - pipeline(connection.newJedisResult(connection.getRequiredPipeline().set(key, value, params), - Converters.stringToBooleanConverter(), () -> false)); - return null; - } - if (isQueueing()) { - - transaction(connection.newJedisResult(connection.getRequiredTransaction().set(key, value, params), - Converters.stringToBooleanConverter(), () -> false)); - return null; - } - - return Converters.stringToBoolean(connection.getJedis().set(key, value, params)); - - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::set, MultiKeyPipelineBase::set, key, value, params) + .getOrElse(Converters.stringToBooleanConverter(), () -> false); } /* @@ -193,22 +126,8 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().setnx(key, value), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().setnx(key, value), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().setnx(key, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - + return connection.invoke().from(BinaryJedis::setnx, MultiKeyPipelineBase::setnx, key, value) + .get(Converters.longToBoolean()); } /* @@ -225,21 +144,8 @@ class JedisStringCommands implements RedisStringCommands { throw new IllegalArgumentException("Time must be less than Integer.MAX_VALUE for setEx in Jedis."); } - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().setex(key, (int) seconds, value), - Converters.stringToBooleanConverter(), () -> false)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().setex(key, (int) seconds, value), - Converters.stringToBooleanConverter(), () -> false)); - return null; - } - return Converters.stringToBoolean(connection.getJedis().setex(key, (int) seconds, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::setex, MultiKeyPipelineBase::setex, key, (int) seconds, value) + .getOrElse(Converters.stringToBooleanConverter(), () -> false); } /* @@ -252,21 +158,8 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().psetex(key, milliseconds, value), - Converters.stringToBooleanConverter(), () -> false)); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().psetex(key, milliseconds, value), - Converters.stringToBooleanConverter(), () -> false)); - return null; - } - return Converters.stringToBoolean(connection.getJedis().psetex(key, milliseconds, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::psetex, MultiKeyPipelineBase::psetex, key, milliseconds, value) + .getOrElse(Converters.stringToBooleanConverter(), () -> false); } /* @@ -278,22 +171,8 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(tuples, "Tuples must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().mset(JedisConverters.toByteArrays(tuples)), - Converters.stringToBooleanConverter())); - return null; - } - if (isQueueing()) { - transaction( - connection.newJedisResult(connection.getRequiredTransaction().mset(JedisConverters.toByteArrays(tuples)), - Converters.stringToBooleanConverter())); - return null; - } - return Converters.stringToBoolean(connection.getJedis().mset(JedisConverters.toByteArrays(tuples))); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::mset, MultiKeyPipelineBase::mset, JedisConverters.toByteArrays(tuples)) + .get(Converters.stringToBooleanConverter()); } /* @@ -305,23 +184,9 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(tuples, "Tuples must not be null!"); - try { - if (isPipelined()) { - pipeline( - connection.newJedisResult(connection.getRequiredPipeline().msetnx(JedisConverters.toByteArrays(tuples)), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction( - connection.newJedisResult(connection.getRequiredTransaction().msetnx(JedisConverters.toByteArrays(tuples)), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().msetnx(JedisConverters.toByteArrays(tuples))); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke() + .from(BinaryJedis::msetnx, MultiKeyPipelineBase::msetnx, JedisConverters.toByteArrays(tuples)) + .get(Converters.longToBoolean()); } /* @@ -333,19 +198,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().incr(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().incr(key))); - return null; - } - return connection.getJedis().incr(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::incr, MultiKeyPipelineBase::incr, key); } /* @@ -357,20 +210,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().incrBy(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().incrBy(key, value))); - return null; - } - return connection.getJedis().incrBy(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - + return connection.invoke().just(BinaryJedis::incrBy, MultiKeyPipelineBase::incrBy, key, value); } /* @@ -382,19 +222,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().incrByFloat(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().incrByFloat(key, value))); - return null; - } - return connection.getJedis().incrByFloat(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::incrByFloat, MultiKeyPipelineBase::incrByFloat, key, value); } /* @@ -406,20 +234,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().decr(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().decr(key))); - return null; - } - return connection.getJedis().decr(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - + return connection.invoke().just(BinaryJedis::decr, MultiKeyPipelineBase::decr, key); } /* @@ -431,19 +246,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().decrBy(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().decrBy(key, value))); - return null; - } - return connection.getJedis().decrBy(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::decrBy, MultiKeyPipelineBase::decrBy, key, value); } /* @@ -456,19 +259,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().append(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().append(key, value))); - return null; - } - return connection.getJedis().append(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::append, MultiKeyPipelineBase::append, key, value); } /* @@ -480,19 +271,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().getrange(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().getrange(key, start, end))); - return null; - } - return connection.getJedis().getrange(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::getrange, MultiKeyPipelineBase::getrange, key, start, end); } /* @@ -505,19 +284,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newStatusResult(connection.getRequiredPipeline().setrange(key, offset, value))); - return; - } - if (isQueueing()) { - transaction(connection.newStatusResult(connection.getRequiredTransaction().setrange(key, offset, value))); - return; - } - connection.getJedis().setrange(key, offset, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + connection.invokeStatus().just(BinaryJedis::setrange, MultiKeyPipelineBase::setrange, key, offset, value); } /* @@ -529,26 +296,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().getbit(key, offset))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().getbit(key, offset))); - return null; - } - // compatibility check for Jedis 2.0.0 - Object getBit = connection.getJedis().getbit(key, offset); - // Jedis 2.0 - if (getBit instanceof Long) { - return (((Long) getBit) == 0 ? Boolean.FALSE : Boolean.TRUE); - } - // Jedis 2.1 - return ((Boolean) getBit); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::getbit, MultiKeyPipelineBase::getbit, key, offset); } /* @@ -560,23 +308,8 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - - pipeline(connection - .newJedisResult(connection.getRequiredPipeline().setbit(key, offset, JedisConverters.toBit(value)))); - return null; - } - if (isQueueing()) { - transaction(connection - .newJedisResult(connection.getRequiredTransaction().setbit(key, offset, JedisConverters.toBit(value)))); - return null; - } - return connection.getJedis().setbit(key, offset, JedisConverters.toBit(value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - + return connection.invoke().just(BinaryJedis::setbit, MultiKeyPipelineBase::setbit, key, offset, + JedisConverters.toBit(value)); } /* @@ -588,19 +321,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().bitcount(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().bitcount(key))); - return null; - } - return connection.getJedis().bitcount(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::bitcount, MultiKeyPipelineBase::bitcount, key); } /* @@ -612,19 +333,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().bitcount(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().bitcount(key, start, end))); - return null; - } - return connection.getJedis().bitcount(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::bitcount, MultiKeyPipelineBase::bitcount, key, start, end); } /* @@ -637,9 +346,8 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(subCommands, "Command must not be null!"); - byte[][] args = ByteUtils.mergeArrays(key, JedisConverters.toBitfieldCommandArguments(subCommands)); - - return connection.execute("BITFIELD", args, Client::getIntegerMultiBulkReply, JedisClientUtils::getResponse); + return connection.invoke().just(BinaryJedis::bitfield, MultiKeyPipelineBase::bitfield, key, + JedisConverters.toBitfieldCommandArguments(subCommands)); } /* @@ -656,21 +364,8 @@ class JedisStringCommands implements RedisStringCommands { throw new UnsupportedOperationException("Bitop NOT should only be performed against one key"); } - try { - if (isPipelined()) { - pipeline(connection - .newJedisResult(connection.getRequiredPipeline().bitop(JedisConverters.toBitOp(op), destination, keys))); - return null; - } - if (isQueueing()) { - transaction(connection - .newJedisResult(connection.getRequiredTransaction().bitop(JedisConverters.toBitOp(op), destination, keys))); - return null; - } - return connection.getJedis().bitop(JedisConverters.toBitOp(op), destination, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::bitop, MultiKeyPipelineBase::bitop, JedisConverters.toBitOp(op), + destination, keys); } /* @@ -684,30 +379,16 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(range, "Range must not be null! Use Range.unbounded() instead."); - BitPosParams params = null; if (range.getLowerBound().isBounded()) { - params = range.getUpperBound().isBounded() + + BitPosParams params = range.getUpperBound().isBounded() ? new BitPosParams(range.getLowerBound().getValue().get(), range.getUpperBound().getValue().get()) : new BitPosParams(range.getLowerBound().getValue().get()); + + return connection.invoke().just(BinaryJedis::bitpos, MultiKeyPipelineBase::bitpos, key, bit, params); } - try { - if (isPipelined()) { - - pipeline(connection.newJedisResult(params != null ? connection.getRequiredPipeline().bitpos(key, bit, params) - : connection.getRequiredPipeline().bitpos(key, bit))); - return null; - } - if (isQueueing()) { - transaction( - connection.newJedisResult(params != null ? connection.getRequiredTransaction().bitpos(key, bit, params) - : connection.getRequiredTransaction().bitpos(key, bit))); - return null; - } - return params != null ? connection.getJedis().bitpos(key, bit, params) : connection.getJedis().bitpos(key, bit); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::bitpos, MultiKeyPipelineBase::bitpos, key, bit); } /* @@ -719,38 +400,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().strlen(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().strlen(key))); - return null; - } - return connection.getJedis().strlen(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::strlen, MultiKeyPipelineBase::strlen, key); } - 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); - } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java index 203cfeda5..61665d5fa 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java @@ -15,6 +15,9 @@ */ package org.springframework.data.redis.connection.jedis; +import redis.clients.jedis.BinaryJedis; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.MultiKeyPipelineBase; import redis.clients.jedis.ScanParams; import redis.clients.jedis.ScanResult; import redis.clients.jedis.ZParams; @@ -55,21 +58,8 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zadd(key, score, value), - JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zadd(key, score, value), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(connection.getJedis().zadd(key, score, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().from(BinaryJedis::zadd, MultiKeyPipelineBase::zadd, key, score, value) + .get(JedisConverters::toBoolean); } /* @@ -82,21 +72,8 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(tuples, "Tuples must not be null!"); - try { - if (isPipelined()) { - pipeline( - connection.newJedisResult(connection.getRequiredPipeline().zadd(key, JedisConverters.toTupleMap(tuples)))); - return null; - } - if (isQueueing()) { - transaction(connection - .newJedisResult(connection.getRequiredTransaction().zadd(key, JedisConverters.toTupleMap(tuples)))); - return null; - } - return connection.getJedis().zadd(key, JedisConverters.toTupleMap(tuples)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zadd, MultiKeyPipelineBase::zadd, key, + JedisConverters.toTupleMap(tuples)); } /* @@ -110,19 +87,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(values, "Values must not be null!"); Assert.noNullElements(values, "Values must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrem(key, values))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrem(key, values))); - return null; - } - return connection.getJedis().zrem(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zrem, MultiKeyPipelineBase::zrem, key, values); } /* @@ -135,19 +100,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zincrby(key, increment, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zincrby(key, increment, value))); - return null; - } - return connection.getJedis().zincrby(key, increment, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zincrby, MultiKeyPipelineBase::zincrby, key, increment, value); } /* @@ -160,19 +113,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrank(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrank(key, value))); - return null; - } - return connection.getJedis().zrank(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zrank, MultiKeyPipelineBase::zrank, key, value); } /* @@ -184,19 +125,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrevrank(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrevrank(key, value))); - return null; - } - return connection.getJedis().zrevrank(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zrevrank, MultiKeyPipelineBase::zrevrank, key, value); } /* @@ -208,19 +137,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrange(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrange(key, start, end))); - return null; - } - return connection.getJedis().zrange(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zrange, MultiKeyPipelineBase::zrange, key, start, end); } /* @@ -232,21 +149,9 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrangeWithScores(key, start, end), - JedisConverters.tupleSetToTupleSet())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrangeWithScores(key, start, end), - JedisConverters.tupleSetToTupleSet())); - return null; - } - return JedisConverters.toTupleSet(connection.getJedis().zrangeWithScores(key, start, end)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke() + .from(BinaryJedis::zrangeWithScores, MultiKeyPipelineBase::zrangeWithScores, key, start, end) + .get(JedisConverters.tupleSetToTupleSet()); } /* @@ -263,38 +168,15 @@ class JedisZSetCommands implements RedisZSetCommands { byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); - try { - if (isPipelined()) { - if (!limit.isUnlimited()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrangeByScoreWithScores(key, min, max, - limit.getOffset(), limit.getCount()), JedisConverters.tupleSetToTupleSet())); - } else { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrangeByScoreWithScores(key, min, max), - JedisConverters.tupleSetToTupleSet())); - } - return null; - } - - if (isQueueing()) { - if (!limit.isUnlimited()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrangeByScoreWithScores(key, min, - max, limit.getOffset(), limit.getCount()), JedisConverters.tupleSetToTupleSet())); - } else { - transaction( - connection.newJedisResult(connection.getRequiredTransaction().zrangeByScoreWithScores(key, min, max), - JedisConverters.tupleSetToTupleSet())); - } - return null; - } - - if (!limit.isUnlimited()) { - return JedisConverters.toTupleSet( - connection.getJedis().zrangeByScoreWithScores(key, min, max, limit.getOffset(), limit.getCount())); - } - return JedisConverters.toTupleSet(connection.getJedis().zrangeByScoreWithScores(key, min, max)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + if (!limit.isUnlimited()) { + return connection.invoke().from(BinaryJedis::zrangeByScoreWithScores, + MultiKeyPipelineBase::zrangeByScoreWithScores, key, min, max, limit.getOffset(), limit.getCount()) + .get(JedisConverters.tupleSetToTupleSet()); } + + return connection.invoke() + .from(BinaryJedis::zrangeByScoreWithScores, MultiKeyPipelineBase::zrangeByScoreWithScores, key, min, max) + .get(JedisConverters.tupleSetToTupleSet()); } /* @@ -306,19 +188,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrevrange(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrevrange(key, start, end))); - return null; - } - return connection.getJedis().zrevrange(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zrevrange, MultiKeyPipelineBase::zrevrange, key, start, end); } /* @@ -330,21 +200,9 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrevrangeWithScores(key, start, end), - JedisConverters.tupleSetToTupleSet())); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrevrangeWithScores(key, start, end), - JedisConverters.tupleSetToTupleSet())); - return null; - } - return JedisConverters.toTupleSet(connection.getJedis().zrevrangeWithScores(key, start, end)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke() + .from(BinaryJedis::zrevrangeWithScores, MultiKeyPipelineBase::zrevrangeWithScores, key, start, end) + .get(JedisConverters.tupleSetToTupleSet()); } /* @@ -361,34 +219,13 @@ class JedisZSetCommands implements RedisZSetCommands { byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); - try { - if (isPipelined()) { - if (!limit.isUnlimited()) { - pipeline(connection.newJedisResult( - connection.getRequiredPipeline().zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount()))); - } else { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrevrangeByScore(key, max, min))); - } - return null; - } - - if (isQueueing()) { - if (!limit.isUnlimited()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrevrangeByScore(key, max, min, - limit.getOffset(), limit.getCount()))); - } else { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrevrangeByScore(key, max, min))); - } - return null; - } - - if (!limit.isUnlimited()) { - return connection.getJedis().zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount()); - } - return connection.getJedis().zrevrangeByScore(key, max, min); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + if (!limit.isUnlimited()) { + return connection.invoke().just(BinaryJedis::zrevrangeByScore, MultiKeyPipelineBase::zrevrangeByScore, key, max, + min, limit.getOffset(), limit.getCount()); } + + return connection.invoke().just(BinaryJedis::zrevrangeByScore, MultiKeyPipelineBase::zrevrangeByScore, key, max, + min); } /* @@ -405,38 +242,15 @@ class JedisZSetCommands implements RedisZSetCommands { byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); - try { - if (isPipelined()) { - if (!limit.isUnlimited()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrevrangeByScoreWithScores(key, max, min, - limit.getOffset(), limit.getCount()), JedisConverters.tupleSetToTupleSet())); - } else { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrevrangeByScoreWithScores(key, max, min), - JedisConverters.tupleSetToTupleSet())); - } - return null; - } - - if (isQueueing()) { - if (!limit.isUnlimited()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrevrangeByScoreWithScores(key, max, - min, limit.getOffset(), limit.getCount()), JedisConverters.tupleSetToTupleSet())); - } else { - transaction( - connection.newJedisResult(connection.getRequiredTransaction().zrevrangeByScoreWithScores(key, max, min), - JedisConverters.tupleSetToTupleSet())); - } - return null; - } - - if (!limit.isUnlimited()) { - return JedisConverters.toTupleSet( - connection.getJedis().zrevrangeByScoreWithScores(key, max, min, limit.getOffset(), limit.getCount())); - } - return JedisConverters.toTupleSet(connection.getJedis().zrevrangeByScoreWithScores(key, max, min)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + if (!limit.isUnlimited()) { + return connection.invoke().from(BinaryJedis::zrevrangeByScoreWithScores, + MultiKeyPipelineBase::zrevrangeByScoreWithScores, key, max, min, limit.getOffset(), limit.getCount()) + .get(JedisConverters.tupleSetToTupleSet()); } + + return connection.invoke() + .from(BinaryJedis::zrevrangeByScoreWithScores, MultiKeyPipelineBase::zrevrangeByScoreWithScores, key, max, min) + .get(JedisConverters.tupleSetToTupleSet()); } /* @@ -448,19 +262,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zcount(key, min, max))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zcount(key, min, max))); - return null; - } - return connection.getJedis().zcount(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zcount, MultiKeyPipelineBase::zcount, key, min, max); } /* @@ -476,19 +278,7 @@ class JedisZSetCommands implements RedisZSetCommands { byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zcount(key, min, max))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zcount(key, min, max))); - return null; - } - return connection.getJedis().zcount(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zcount, MultiKeyPipelineBase::zcount, key, min, max); } /* @@ -504,19 +294,7 @@ class JedisZSetCommands implements RedisZSetCommands { byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES); byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zlexcount(key, min, max))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zlexcount(key, min, max))); - return null; - } - return connection.getJedis().zlexcount(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zlexcount, MultiKeyPipelineBase::zlexcount, key, min, max); } /* @@ -528,19 +306,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zcard(key))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zcard(key))); - return null; - } - return connection.getJedis().zcard(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zcard, MultiKeyPipelineBase::zcard, key); } /* @@ -553,19 +319,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); Assert.notNull(value, "Value must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zscore(key, value))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zscore(key, value))); - return null; - } - return connection.getJedis().zscore(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zscore, MultiKeyPipelineBase::zscore, key, value); } /* @@ -577,19 +331,8 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zremrangeByRank(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zremrangeByRank(key, start, end))); - return null; - } - return connection.getJedis().zremrangeByRank(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zremrangeByRank, MultiKeyPipelineBase::zremrangeByRank, key, start, + end); } /* @@ -605,19 +348,8 @@ class JedisZSetCommands implements RedisZSetCommands { byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zremrangeByScore(key, min, max))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zremrangeByScore(key, min, max))); - return null; - } - return connection.getJedis().zremrangeByScore(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zremrangeByScore, MultiKeyPipelineBase::zremrangeByScore, key, min, + max); } /* @@ -634,21 +366,10 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.isTrue(weights.size() == sets.length, () -> String .format("The number of weights (%d) must match the number of source sets (%d)!", weights.size(), sets.length)); - try { - ZParams zparams = new ZParams().weights(weights.toArray()).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); + ZParams zparams = new ZParams().weights(weights.toArray()).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zunionstore(destKey, zparams, sets))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zunionstore(destKey, zparams, sets))); - return null; - } - return connection.getJedis().zunionstore(destKey, zparams, sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zunionstore, MultiKeyPipelineBase::zunionstore, destKey, zparams, + sets); } /* @@ -662,19 +383,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(sets, "Source sets must not be null!"); Assert.noNullElements(sets, "Source sets must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zunionstore(destKey, sets))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zunionstore(destKey, sets))); - return null; - } - return connection.getJedis().zunionstore(destKey, sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zunionstore, MultiKeyPipelineBase::zunionstore, destKey, sets); } /* @@ -690,21 +399,10 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.isTrue(weights.size() == sets.length, () -> String .format("The number of weights (%d) must match the number of source sets (%d)!", weights.size(), sets.length)); - try { - ZParams zparams = new ZParams().weights(weights.toArray()).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); + ZParams zparams = new ZParams().weights(weights.toArray()).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zinterstore(destKey, zparams, sets))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zinterstore(destKey, zparams, sets))); - return null; - } - return connection.getJedis().zinterstore(destKey, zparams, sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zinterstore, MultiKeyPipelineBase::zinterstore, destKey, zparams, + sets); } /* @@ -718,19 +416,7 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(sets, "Source sets must not be null!"); Assert.noNullElements(sets, "Source sets must not contain null elements!"); - try { - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zinterstore(destKey, sets))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zinterstore(destKey, sets))); - return null; - } - return connection.getJedis().zinterstore(destKey, sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke().just(BinaryJedis::zinterstore, MultiKeyPipelineBase::zinterstore, destKey, sets); } /* @@ -787,20 +473,9 @@ class JedisZSetCommands implements RedisZSetCommands { Assert.notNull(key, "Key must not be null!"); - try { - String keyStr = new String(key, StandardCharsets.UTF_8); - if (isPipelined()) { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrangeByScore(keyStr, min, max))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrangeByScore(keyStr, min, max))); - return null; - } - return JedisConverters.stringSetToByteSet().convert(connection.getJedis().zrangeByScore(keyStr, min, max)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + String keyStr = new String(key, StandardCharsets.UTF_8); + return connection.invoke().from(Jedis::zrangeByScore, MultiKeyPipelineBase::zrangeByScore, keyStr, min, max) + .get(JedisConverters.stringSetToByteSet()); } /* @@ -817,24 +492,11 @@ class JedisZSetCommands implements RedisZSetCommands { throw new IllegalArgumentException( "Offset and count must be less than Integer.MAX_VALUE for zRangeByScore in Jedis."); } + String keyStr = new String(key, StandardCharsets.UTF_8); - try { - String keyStr = new String(key, StandardCharsets.UTF_8); - if (isPipelined()) { - pipeline(connection.newJedisResult( - connection.getRequiredPipeline().zrangeByScore(keyStr, min, max, (int) offset, (int) count))); - return null; - } - if (isQueueing()) { - transaction(connection.newJedisResult( - connection.getRequiredTransaction().zrangeByScore(keyStr, min, max, (int) offset, (int) count))); - return null; - } - return JedisConverters.stringSetToByteSet() - .convert(connection.getJedis().zrangeByScore(keyStr, min, max, (int) offset, (int) count)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + return connection.invoke() + .from(Jedis::zrangeByScore, MultiKeyPipelineBase::zrangeByScore, keyStr, min, max, (int) offset, (int) count) + .get(JedisConverters.stringSetToByteSet()); } /* @@ -851,34 +513,12 @@ class JedisZSetCommands implements RedisZSetCommands { byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); - try { - if (isPipelined()) { - if (!limit.isUnlimited()) { - pipeline(connection.newJedisResult( - connection.getRequiredPipeline().zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()))); - } else { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrangeByScore(key, min, max))); - } - return null; - } - - if (isQueueing()) { - if (!limit.isUnlimited()) { - transaction(connection.newJedisResult( - connection.getRequiredTransaction().zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()))); - } else { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrangeByScore(key, min, max))); - } - return null; - } - - if (!limit.isUnlimited()) { - return connection.getJedis().zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()); - } - return connection.getJedis().zrangeByScore(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + if (!limit.isUnlimited()) { + return connection.invoke().just(BinaryJedis::zrangeByScore, MultiKeyPipelineBase::zrangeByScore, key, min, max, + limit.getOffset(), limit.getCount()); } + + return connection.invoke().just(BinaryJedis::zrangeByScore, MultiKeyPipelineBase::zrangeByScore, key, min, max); } /* @@ -895,34 +535,12 @@ class JedisZSetCommands implements RedisZSetCommands { byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES); byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES); - try { - if (isPipelined()) { - if (!limit.isUnlimited()) { - pipeline(connection.newJedisResult( - connection.getRequiredPipeline().zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()))); - } else { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrangeByLex(key, min, max))); - } - return null; - } - - if (isQueueing()) { - if (!limit.isUnlimited()) { - transaction(connection.newJedisResult( - connection.getRequiredTransaction().zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()))); - } else { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrangeByLex(key, min, max))); - } - return null; - } - - if (!limit.isUnlimited()) { - return connection.getJedis().zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()); - } - return connection.getJedis().zrangeByLex(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + if (!limit.isUnlimited()) { + return connection.invoke().just(BinaryJedis::zrangeByLex, MultiKeyPipelineBase::zrangeByLex, key, min, max, + limit.getOffset(), limit.getCount()); } + + return connection.invoke().just(BinaryJedis::zrangeByLex, MultiKeyPipelineBase::zrangeByLex, key, min, max); } /* @@ -939,54 +557,22 @@ class JedisZSetCommands implements RedisZSetCommands { byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES); byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES); - try { - if (isPipelined()) { - if (!limit.isUnlimited()) { - pipeline(connection.newJedisResult( - connection.getRequiredPipeline().zrevrangeByLex(key, max, min, limit.getOffset(), limit.getCount()))); - } else { - pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrevrangeByLex(key, max, min))); - } - return null; - } - if (isQueueing()) { - if (!limit.isUnlimited()) { - transaction(connection.newJedisResult( - connection.getRequiredTransaction().zrevrangeByLex(key, max, min, limit.getOffset(), limit.getCount()))); - } else { - transaction(connection.newJedisResult(connection.getRequiredTransaction().zrevrangeByLex(key, max, min))); - } - return null; - } - - if (!limit.isUnlimited()) { - return new LinkedHashSet<>( - connection.getJedis().zrevrangeByLex(key, max, min, limit.getOffset(), limit.getCount())); - } - return new LinkedHashSet<>(connection.getJedis().zrevrangeByLex(key, max, min)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + if (!limit.isUnlimited()) { + return connection.invoke().from(BinaryJedis::zrevrangeByLex, MultiKeyPipelineBase::zrevrangeByLex, key, max, min, + limit.getOffset(), limit.getCount()).get(LinkedHashSet::new); } + + return connection.invoke().from(BinaryJedis::zrevrangeByLex, MultiKeyPipelineBase::zrevrangeByLex, key, max, min) + .get(LinkedHashSet::new); } 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); - } } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java index 4b0e3226b..287f7de58 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java @@ -216,11 +216,6 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP @Disabled public void testScriptFlush() {} - @Test - public void testInfoBySection() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testInfoBySection); - } - @Test // DATAREDIS-269 public void clientSetNameWorksCorrectly() { assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::clientSetNameWorksCorrectly); diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineTxIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineTxIntegrationTests.java index e5cd8f124..10ca94ac0 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineTxIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineTxIntegrationTests.java @@ -28,10 +28,6 @@ import org.junit.jupiter.api.Test; */ public class JedisConnectionPipelineTxIntegrationTests extends JedisConnectionTransactionIntegrationTests { - @Disabled("Jedis issue: Pipeline tries to return String instead of List") - @Test - public void testGetConfig() {} - @Test @Disabled public void testRestoreBadData() {}