From c7eef8fcff00ae79852fe18fed72d8a51173f73b Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 4 Feb 2021 14:39:43 +0100 Subject: [PATCH] Introduce JedisInvoker. We now use JedisInvoker to call Jedis and Pipeline methods for synchronous, pipelining, and transactional execution models. JedisInvoker captures the method invocation as functional utility and allows conversion of results: Long result = invoker.just(BinaryJedis::geoadd, MultiKeyPipelineBase:geoadd, key, point.getX(), point.getY(), member); Closes #1951 Original Pull Request: #1960 --- .../connection/jedis/JedisConnection.java | 253 ++-- .../connection/jedis/JedisGeoCommands.java | 229 +--- .../connection/jedis/JedisHashCommands.java | 204 +--- .../jedis/JedisHyperLogLogCommands.java | 65 +- .../redis/connection/jedis/JedisInvoker.java | 1029 +++++++++++++++++ .../connection/jedis/JedisKeyCommands.java | 442 +------ .../connection/jedis/JedisListCommands.java | 277 +---- .../redis/connection/jedis/JedisResult.java | 2 +- .../jedis/JedisScriptReturnConverter.java | 3 +- .../jedis/JedisScriptingCommands.java | 85 +- .../connection/jedis/JedisServerCommands.java | 270 +---- .../connection/jedis/JedisSetCommands.java | 240 +--- .../connection/jedis/JedisStringCommands.java | 436 +------ .../connection/jedis/JedisZSetCommands.java | 576 ++------- ...disConnectionPipelineIntegrationTests.java | 5 - ...sConnectionPipelineTxIntegrationTests.java | 4 - 16 files changed, 1494 insertions(+), 2626 deletions(-) create mode 100644 src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java 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() {}