diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..aaabe28b98 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +src/test/java/io/redis/examples/* @dmaier-redislabs diff --git a/.github/release-drafter-config.yml b/.github/release-drafter-config.yml index edc2911f43..4607da071c 100644 --- a/.github/release-drafter-config.yml +++ b/.github/release-drafter-config.yml @@ -1,5 +1,7 @@ name-template: '$NEXT_MINOR_VERSION' tag-template: 'v$NEXT_MINOR_VERSION' +filter-by-commitish: true +commitish: master autolabeler: - label: 'maintenance' files: @@ -35,6 +37,8 @@ categories: labels: - 'maintenance' - 'dependencies' + - 'documentation' + - 'docs' - 'testing' change-template: '- $TITLE (#$NUMBER)' exclude-labels: diff --git a/.github/spellcheck-settings.yml b/.github/spellcheck-settings.yml new file mode 100644 index 0000000000..07b400f063 --- /dev/null +++ b/.github/spellcheck-settings.yml @@ -0,0 +1,28 @@ +matrix: +- name: Markdown + expect_match: false + apsell: + lang: en + d: en_US + ignore-case: true + dictionary: + wordlists: + - .github/wordlist.txt + output: wordlist.dic + pipeline: + - pyspelling.filters.markdown: + markdown_extensions: + - markdown.extensions.extra: + - pyspelling.filters.html: + comments: false + attributes: + - alt + ignores: + - ':matches(code, pre)' + - code + - pre + - blockquote + - img + sources: + - '*.md' + - 'docs/**' diff --git a/.github/wordlist.txt b/.github/wordlist.txt new file mode 100644 index 0000000000..7d0d85f49d --- /dev/null +++ b/.github/wordlist.txt @@ -0,0 +1,311 @@ +!!!Spelling check failed!!! +APM +ARGV +BFCommands +BitOP +BitPosParams +BuilderFactory +CFCommands +CMSCommands +CallNotPermittedException +CircuitBreaker +ClientKillParams +ClusterNode +ClusterNodes +ClusterPipeline +ClusterPubSub +ConnectionPool +CoreCommands +EVAL +EVALSHA +Failback +Failover +GSON +GenericObjectPool +GenericObjectPoolConfig +GeoAddParams +GeoRadiusParam +GeoRadiusStoreParam +GeoUnit +GraphCommands +Grokzen's +HostAndPort +HostnameVerifier +INCR +IOError +Instrumentations +JDK +JSONArray +JSONCommands +Jaeger +Javadocs +Jedis +JedisCluster +JedisConnectionException +JedisPool +JedisPooled +JedisShardInfo +ListPosition +Ludovico +Magnocavallo +McCurdy +NOSCRIPT +NUMPAT +NUMPT +NUMSUB +OSS +OpenCensus +OpenTelemetry +OpenTracing +Otel +POJO +POJOs +PubSub +Queable +READONLY +RediSearch +RediSearchCommands +RedisBloom +RedisCluster +RedisClusterCommands +RedisClusterException +RedisClusters +RedisGraph +RedisInstrumentor +RedisJSON +RedisTimeSeries +SHA +SSLParameters +SSLSocketFactory +SearchCommands +SentinelCommands +SentinelConnectionPool +ShardInfo +Sharded +Solovyov +SortingParams +SpanKind +Specfiying +StatusCode +StreamEntryID +TCP +TOPKCommands +Throwable +TimeSeriesCommands +URI +UnblockType +UnifiedJedis +Uptrace +ValueError +WATCHed +WatchError +XTrimParams +ZAddParams +ZParams +aclDelUser +api +approximateLength +arg +args +async +asyncio +autoclass +automodule +backoff +bdb +behaviour +bitcount +bitop +bitpos +bool +boolean +booleans +bysource +charset +clientId +clientKill +clientUnblock +clusterCountKeysInSlot +clusterKeySlot +configs +consumerName +consumername +cumbersome +dbIndex +dbSize +decr +decrBy +del +destKey +dev +dstKey +dstkey +eg +exc +expireAt +failback +failover +faoliver +firstName +firsttimersonly +fo +genindex +geoadd +georadiusByMemberStore +georadiusStore +getbit +gmail +groupname +hdel +hexists +hincrBy +hincrByFloat +hiredis +hlen +hset +hsetnx +hstrlen +http +idx +iff +incr +incrBy +incrByFloat +ini +json +keyslot +keyspace +keysvalues +kwarg +lastName +lastsave +linsert +linters +llen +localhost +lpush +lpushx +lrem +lua +makeapullrequest +maxLen +maxdepth +maya +memberCoordinateMap +mget +microservice +microservices +millisecondsTimestamp +mset +msetnx +multikey +mykey +newkey +nonatomic +observability +oldkey +opentelemetry +oss +param +params +performant +pexpire +pexpireAt +pfadd +pfcount +pmessage +png +pre +psubscribe +pttl +pubsub +punsubscribe +py +pypi +quickstart +readonly +readwrite +redis +redismodules +reimplemented +reinitialization +renamenx +replicaof +repo +rpush +rpushx +runtime +sadd +scard +scoreMembers +sdiffstore +sedrik +setbit +setnx +setrange +sinterstore +sismember +slowlogLen +smove +sortingParameters +srcKey +srcKeys +srckey +ssl +storeParam +str +strlen +stunnel +subcommands +sunionstore +thevalueofmykey +timeseries +toctree +topk +tox +triaging +ttl +txt +un +unblockType +unicode +unixTime +unlink +untyped +url +virtualenv +waitReplicas +whenver +www +xack +xdel +xgroupDelConsumer +xgroupDestroy +xlen +xtrim +zadd +zcard +zcount +zdiffStore +zincrby +zinterstore +zlexcount +zpopmax +zpopmin +zrandmember +zrandmemberWithScores +zrange +zrangeByLex +zrangeByScore +zrangeByScoreWithScores +zrangeWithScores +zrem +zremrangeByLex +zremrangeByRank +zremrangeByScore +zrevrange +zrevrangeByLex +zrevrangeByScore +zrevrangeByScoreWithScores +zrevrangeWithScores +zunionstore diff --git a/.github/workflows/doctests.yml b/.github/workflows/doctests.yml index 8122b40b20..0062c2da24 100644 --- a/.github/workflows/doctests.yml +++ b/.github/workflows/doctests.yml @@ -2,6 +2,10 @@ name: Documentation Tests on: push: + tags-ignore: + - '*' + branches: + - 'emb-examples' pull_request: workflow_dispatch: @@ -32,4 +36,4 @@ jobs: distribution: 'temurin' - name: Run doctests run: | - mvn -Pdoctests test \ No newline at end of file + mvn -Pdoctests test diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index e6907dcaef..fd651fa6a4 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -10,15 +10,14 @@ on: - '**/*.rst' branches: - master - - '[0-9].[0-9]' - - '[0-9].x' + - '[0-9].*' pull_request: branches: - master - - '[0-9].[0-9]' - - '[0-9].x' + - '[0-9].*' schedule: - cron: '0 1 * * *' # nightly build + workflow_dispatch: jobs: diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 6c8ad1a962..8a409b8331 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -6,7 +6,8 @@ on: push: branches: - master - - '[0-9].[0-9]' + - '[0-9].x' + workflow_dispatch: jobs: diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml new file mode 100644 index 0000000000..e152841553 --- /dev/null +++ b/.github/workflows/spellcheck.yml @@ -0,0 +1,14 @@ +name: spellcheck +on: + pull_request: +jobs: + check-spelling: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Check Spelling + uses: rojopolis/spellcheck-github-actions@0.33.1 + with: + config_path: .github/spellcheck-settings.yml + task_name: Markdown diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml new file mode 100644 index 0000000000..54bf059fba --- /dev/null +++ b/.github/workflows/stale-issues.yml @@ -0,0 +1,25 @@ +name: "Close stale issues" +on: + schedule: + - cron: "0 0 * * *" + +permissions: {} +jobs: + stale: + permissions: + issues: write # to close stale issues (actions/stale) + pull-requests: write # to close stale PRs (actions/stale) + + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue is marked stale. It will be closed in 30 days if it is not updated.' + stale-pr-message: 'This pull request is marked stale. It will be closed in 30 days if it is not updated.' + days-before-stale: 365 + days-before-close: 30 + stale-issue-label: "stale" + stale-pr-label: "stale" + operations-per-run: 10 + remove-stale-when-updated: false diff --git a/.github/workflows/version-and-release.yml b/.github/workflows/version-and-release.yml index 007d8875e8..7c996e5bd5 100644 --- a/.github/workflows/version-and-release.yml +++ b/.github/workflows/version-and-release.yml @@ -16,7 +16,7 @@ jobs: run: | realversion="${GITHUB_REF/refs\/tags\//}" realversion="${realversion//v/}" - echo "::set-output name=VERSION::$realversion" + echo "VERSION=$realversion" >> $GITHUB_OUTPUT - name: Set up publishing to maven central uses: actions/setup-java@v2 @@ -32,14 +32,14 @@ jobs: - name: Install gpg key run: | - cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import + cat <(echo -e "${{ secrets.OSSH_GPG_SECRET_KEY }}") | gpg --batch --import gpg --list-secret-keys --keyid-format LONG - name: Publish run: | mvn --no-transfer-progress \ --batch-mode \ - -Dgpg.passphrase='${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }}' \ + -Dgpg.passphrase='${{ secrets.OSSH_GPG_SECRET_KEY_PASSWORD }}' \ -DskipTests deploy -P release env: MAVEN_USERNAME: ${{secrets.OSSH_USERNAME}} diff --git a/Makefile b/Makefile index 2987ad80dd..6e63f1b6ce 100644 --- a/Makefile +++ b/Makefile @@ -209,7 +209,7 @@ daemonize yes protected-mode no requirepass cluster port 7379 -cluster-node-timeout 50 +cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node1.pid logfile /tmp/redis_cluster_node1.log save "" @@ -223,7 +223,7 @@ daemonize yes protected-mode no requirepass cluster port 7380 -cluster-node-timeout 50 +cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node2.pid logfile /tmp/redis_cluster_node2.log save "" @@ -237,7 +237,7 @@ daemonize yes protected-mode no requirepass cluster port 7381 -cluster-node-timeout 50 +cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node3.pid logfile /tmp/redis_cluster_node3.log save "" @@ -251,7 +251,7 @@ daemonize yes protected-mode no requirepass cluster port 7382 -cluster-node-timeout 50 +cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node4.pid logfile /tmp/redis_cluster_node4.log save "" @@ -265,7 +265,7 @@ daemonize yes protected-mode no requirepass cluster port 7383 -cluster-node-timeout 5000 +cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node5.pid logfile /tmp/redis_cluster_node5.log save "" diff --git a/README.md b/README.md index f0a5d6ae61..4c7c507d21 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE.txt) [![Integration](https://github.com/redis/jedis/actions/workflows/integration.yml/badge.svg?branch=master)](https://github.com/redis/jedis/actions/workflows/integration.yml) [![codecov](https://codecov.io/gh/redis/jedis/branch/master/graph/badge.svg?token=pAstxAAjYo)](https://codecov.io/gh/redis/jedis) -[![Discord](https://img.shields.io/discord/697882427875393627?style=flat-square)](https://discord.gg/qRhBuY8Z) +[![Discord](https://img.shields.io/discord/697882427875393627?style=flat-square)](https://discord.gg/redis) ## What is Jedis? @@ -14,26 +14,37 @@ Jedis is a Java client for [Redis](https://github.com/redis/redis "Redis") desig Are you looking for a high-level library to handle object mapping? See [redis-om-spring](https://github.com/redis/redis-om-spring)! -## Contributing +## How do I Redis? -We'd love your contributions! +[Learn for free at Redis University](https://university.redis.com/) -**Bug reports** are always welcome! [You can open a bug report on GitHub](https://github.com/redis/jedis/issues/new). +[Build faster with the Redis Launchpad](https://launchpad.redis.com/) -You can also **contribute documentation** -- or anything to improve Jedis. Please see -[contribution guideline](https://github.com/redis/jedis/blob/master/.github/CONTRIBUTING.md) for more details. +[Try the Redis Cloud](https://redis.com/try-free/) + +[Dive in developer tutorials](https://developer.redis.com/) + +[Join the Redis community](https://redis.com/community/) + +[Work at Redis](https://redis.com/company/careers/jobs/) ## Supported Redis versions -The most recent version of this library supports redis version [5.0](https://github.com/redis/redis/blob/5.0/00-RELEASENOTES), [6.0](https://github.com/redis/redis/blob/6.0/00-RELEASENOTES), [6.2](https://github.com/redis/redis/blob/6.2/00-RELEASENOTES), and [7.0](https://github.com/redis/redis/blob/7.0/00-RELEASENOTES). +The most recent version of this library supports redis version +[5.0](https://github.com/redis/redis/blob/5.0/00-RELEASENOTES), +[6.0](https://github.com/redis/redis/blob/6.0/00-RELEASENOTES), +[6.2](https://github.com/redis/redis/blob/6.2/00-RELEASENOTES), +[7.0](https://github.com/redis/redis/blob/7.0/00-RELEASENOTES) and +[7.2](https://github.com/redis/redis/blob/7.2/00-RELEASENOTES). The table below highlights version compatibility of the most-recent library versions and Redis versions. Compatibility means communication features, and Redis command capabilities. -| Library version | Supported redis versions | JDK Compatibility | -|-----------------|--------------------------------|-------------------| -| 3.9+ | 5.0 and 6.2 Family of releases | 8, 11 | -| >= 4.0 | Version 5.0 to current | 8, 11, 17 | +| Jedis version | Supported Redis versions | JDK Compatibility | +|---------------|--------------------------------|-------------------| +| 3.9+ | 5.0 and 6.2 Family of releases | 8, 11 | +| >= 4.0 | Version 5.0 to current | 8, 11, 17 | +| >= 5.0 | Version 6.0 to current | 8, 11, 17 | ## Getting started @@ -43,7 +54,7 @@ To get started with Jedis, first add it as a dependency in your Java project. If redis.clients jedis - 4.4.3 + 5.0.0 ``` @@ -109,6 +120,13 @@ Now you can use the `JedisCluster` instance and send commands like you would wit jedis.sadd("planets", "Mars"); ``` +## Using Redis modules + +Jedis includes support for [Redis modules](https://redis.io/docs/modules/) such as +[RedisJSON](https://oss.redis.com/redisjson/) and [RediSearch](https://oss.redis.com/redisearch/). + +See the [RedisJSON Jedis](docs/redisjson.md) or [RediSearch Jedis](docs/redisearch.md) for details. + ## Failover Jedis supports retry and failover for your Redis deployments. This is useful when: @@ -127,25 +145,26 @@ You can also check the [latest Jedis Javadocs](https://www.javadoc.io/doc/redis. Some specific use-case examples can be found in [`redis.clients.jedis.examples` package](src/test/java/redis/clients/jedis/examples/) of the test source codes. -## Using Redis modules +## Troubleshooting -Jedis includes support for [Redis modules](https://redis.io/docs/modules/) such as -[RedisJSON](https://oss.redis.com/redisjson/) and [RediSearch](https://oss.redis.com/redisearch/). +If you run into trouble or have any questions, we're here to help! -See the [RedisJSON Jedis](docs/redisjson.md) or [RediSearch Jedis](docs/redisearch.md) for details. +Hit us up on the [Redis Discord Server](http://discord.gg/redis) or +[Jedis GitHub Discussions](https://github.com/redis/jedis/discussions) or +[Jedis mailing list](http://groups.google.com/group/jedis_redis). -## Troubleshooting +## Contributing -If you run into trouble or have any questions, we're here to help! +We'd love your contributions! -Hit us up on the [Redis Discord Server](http://discord.gg/redis) or [open an issue on GitHub](https://github.com/redis/jedis). +Bug reports are always welcome! [You can open a bug report on GitHub](https://github.com/redis/jedis/issues/new). -You can also find help on the [Jedis mailing list](http://groups.google.com/group/jedis_redis) or the -[GitHub Discussions](https://github.com/redis/jedis/discussions). +You can also contribute documentation -- or anything to improve Jedis. Please see +[contribution guideline](https://github.com/redis/jedis/blob/master/.github/CONTRIBUTING.md) for more details. ## License -Jedis is licensed under the [MIT license](https://github.com/redis/jedis/blob/master/LICENSE.txt). +Jedis is licensed under the [MIT license](https://github.com/redis/jedis/blob/master/LICENSE). ## Sponsorship diff --git a/docs/breaking-5.md b/docs/breaking-5.md index 195b08eecc..4a013c3800 100644 --- a/docs/breaking-5.md +++ b/docs/breaking-5.md @@ -113,6 +113,8 @@ - `RedisJsonCommands` and `RedisJsonPipelineCommands` interfaces have been moved into `redis.clients.jedis.json.commands` package. +- `AbortedTransactionException` is removed. + - `Queable` class is removed. - `Params` abstract class is removed. diff --git a/docs/failover.md b/docs/failover.md index 8414e41376..38fdc8c97b 100644 --- a/docs/failover.md +++ b/docs/failover.md @@ -99,8 +99,8 @@ Jedis uses the following retry settings: | Max retry attempts | 3 | Maximum number of retry attempts (including the initial call) | | Retry wait duration | 500 ms | Number of milliseconds to wait between retry attempts | | Wait duration backoff multiplier | 2 | Exponential backoff factor multiplied against wait duration between retries. For example, with a wait duration of 1 second and a multiplier of 2, the retries would occur after 1s, 2s, 4s, 8s, 16s, and so on. | -| Retry included exception list | `JedisConnectionException` | A list of `Throwable` classes that count as failures and should be retried. | -| Retry ignored exception list | Empty list | A list of `Throwable` classes to explicitly ignore for the purposes of retry. | +| Retry included exception list | [JedisConnectionException] | A list of Throwable classes that count as failures and should be retried. | +| Retry ignored exception list | null | A list of Throwable classes to explicitly ignore for the purposes of retry. | To disable retry, set `maxRetryAttempts` to 1. @@ -116,8 +116,16 @@ Jedis uses the following circuit breaker settings: | Failure rate threshold | `50.0f` | Percentage of calls within the sliding window that must fail before the circuit breaker transitions to the `OPEN` state. | | Slow call duration threshold | 60000 ms | Duration threshold above which calls are classified as slow and added to the sliding window. | | Slow call rate threshold | `100.0f` | Percentage of calls within the sliding window that exceed the slow call duration threshold before circuit breaker transitions to the `OPEN` state. | -| Circuit breaker included exception list | `JedisConnectionException` | A list of `Throwable` classes that count as failures and add to the failure rate. | -| Circuit breaker ignored exception list | Empty list | A list of `Throwable` classes to explicitly ignore for failure rate calculations. | | +| Circuit breaker included exception list | [JedisConnectionException] | A list of Throwable classes that count as failures and add to the failure rate. | +| Circuit breaker ignored exception list | null | A list of Throwable classes to explicitly ignore for failure rate calculations. | | + +### Fallback configuration + +Jedis uses the following fallback settings: + +| Setting | Default value | Description | +|-------------------------|-------------------------------------------------------|----------------------------------------------------| +| Fallback exception list | [CallNotPermittedException, JedisConnectionException] | A list of Throwable classes that trigger fallback. | ### Failover callbacks diff --git a/docs/jedis-maven.md b/docs/jedis-maven.md index 1c5b0f2598..6466b1ef3a 100644 --- a/docs/jedis-maven.md +++ b/docs/jedis-maven.md @@ -6,7 +6,7 @@ redis.clients jedis - 4.3.0 + 5.0.0 ``` @@ -28,7 +28,7 @@ and redis.clients jedis - 4.4.0-SNAPSHOT + 5.1.0-SNAPSHOT ``` diff --git a/pom.xml b/pom.xml index afd13e8c0a..a90614bd36 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ jar redis.clients jedis - 5.0.0-SNAPSHOT + 5.2.0-SNAPSHOT Jedis Jedis is a blazingly small and sane Redis java client. https://github.com/redis/jedis @@ -46,9 +46,11 @@ github - 1.7.36 redis.clients.jedis + 1.7.36 1.7.1 + 2.16.1 + 3.2.5 @@ -60,12 +62,12 @@ org.apache.commons commons-pool2 - 2.11.1 + 2.12.0 org.json json - 20230618 + 20240205 com.google.code.gson @@ -73,6 +75,22 @@ 2.10.1 + + + com.kohlschutter.junixsocket + junixsocket-core + 2.9.0 + pom + test + + + + org.locationtech.jts + jts-core + 1.19.0 + test + + junit junit @@ -91,31 +109,26 @@ ${slf4j.version} test - - com.kohlschutter.junixsocket - junixsocket-core - 2.6.1 - pom - test - org.mockito mockito-inline - 3.12.4 + 4.11.0 test com.fasterxml.jackson.core jackson-databind - 2.14.2 + ${jackson.version} test com.fasterxml.jackson.datatype jackson-datatype-jsr310 - 2.14.2 + ${jackson.version} test + + io.github.resilience4j resilience4j-all @@ -158,7 +171,7 @@ org.jacoco jacoco-maven-plugin - 0.8.5 + 0.8.11 @@ -176,7 +189,7 @@ maven-compiler-plugin - 3.11.0 + 3.12.1 1.8 1.8 @@ -184,7 +197,7 @@ maven-surefire-plugin - 3.1.2 + ${maven.surefire.version} ${redis-hosts} @@ -212,7 +225,7 @@ maven-javadoc-plugin - 3.5.0 + 3.6.3 8 false @@ -313,7 +326,7 @@ maven-surefire-plugin - 3.1.2 + ${maven.surefire.version} **/examples/*Example.java diff --git a/src/main/java/redis/clients/jedis/AbstractPipeline.java b/src/main/java/redis/clients/jedis/AbstractPipeline.java new file mode 100644 index 0000000000..f4eb0335dc --- /dev/null +++ b/src/main/java/redis/clients/jedis/AbstractPipeline.java @@ -0,0 +1,26 @@ +package redis.clients.jedis; + +import java.io.Closeable; + +public abstract class AbstractPipeline extends PipeliningBase implements Closeable { + + protected AbstractPipeline(CommandObjects commandObjects) { + super(commandObjects); + } + + @Override + public abstract void close(); + + /** + * Synchronize pipeline by reading all responses. + */ + public abstract void sync(); + + public Response publish(String channel, String message) { + return appendCommand(commandObjects.publish(channel, message)); + } + + public Response publish(byte[] channel, byte[] message) { + return appendCommand(commandObjects.publish(channel, message)); + } +} diff --git a/src/main/java/redis/clients/jedis/AbstractTransaction.java b/src/main/java/redis/clients/jedis/AbstractTransaction.java new file mode 100644 index 0000000000..2a551224fa --- /dev/null +++ b/src/main/java/redis/clients/jedis/AbstractTransaction.java @@ -0,0 +1,39 @@ +package redis.clients.jedis; + +import java.io.Closeable; +import java.util.List; + +public abstract class AbstractTransaction extends PipeliningBase implements Closeable { + + protected AbstractTransaction() { + super(new CommandObjects()); + } + + protected AbstractTransaction(CommandObjects commandObjects) { + super(commandObjects); + } + + public abstract void multi(); + + /** + * Must be called before {@link AbstractTransaction#multi() MULTI}. + */ + public abstract String watch(final String... keys); + + /** + * Must be called before {@link AbstractTransaction#multi() MULTI}. + */ + public abstract String watch(final byte[]... keys); + + public abstract String unwatch(); + + @Override public abstract void close(); + + public abstract List exec(); + + public abstract String discard(); + + public Response waitReplicas(int replicas, long timeout) { + return appendCommand(commandObjects.waitReplicas(replicas, timeout)); + } +} diff --git a/src/main/java/redis/clients/jedis/BuilderFactory.java b/src/main/java/redis/clients/jedis/BuilderFactory.java index 20a061d6b9..18bcc5a31c 100644 --- a/src/main/java/redis/clients/jedis/BuilderFactory.java +++ b/src/main/java/redis/clients/jedis/BuilderFactory.java @@ -997,6 +997,155 @@ public Map build(Object data) { } }; + public static final Builder> LATENCY_LATEST_RESPONSE = new Builder>() { + @Override + public Map build(Object data) { + if (data == null) { + return null; + } + + List rawList = (List) data; + Map map = new HashMap<>(rawList.size()); + + for (Object rawLatencyLatestInfo : rawList) { + if (rawLatencyLatestInfo == null) { + continue; + } + + LatencyLatestInfo latestInfo = LatencyLatestInfo.LATENCY_LATEST_BUILDER.build(rawLatencyLatestInfo); + String name = latestInfo.getCommand(); + map.put(name, latestInfo); + } + + return map; + } + }; + + public static final Builder> LATENCY_HISTORY_RESPONSE = new Builder>() { + @Override + public List build(Object data) { + if (data == null) { + return null; + } + + List rawList = (List) data; + List response = new ArrayList<>(rawList.size()); + + for (Object rawLatencyHistoryInfo : rawList) { + if (rawLatencyHistoryInfo == null) { + continue; + } + + LatencyHistoryInfo historyInfo = LatencyHistoryInfo.LATENCY_HISTORY_BUILDER.build(rawLatencyHistoryInfo); + response.add(historyInfo); + } + + return response; + } + }; + + private static final Builder>> CLUSTER_SHARD_SLOTS_RANGES = new Builder>>() { + + @Override + public List> build(Object data) { + if (null == data) { + return null; + } + + List rawSlots = (List) data; + List> slotsRanges = new ArrayList<>(); + for (int i = 0; i < rawSlots.size(); i += 2) { + slotsRanges.add(Arrays.asList(rawSlots.get(i), rawSlots.get(i + 1))); + } + return slotsRanges; + } + }; + + private static final Builder> CLUSTER_SHARD_NODE_INFO_LIST + = new Builder>() { + + final Map mappingFunctions = createDecoderMap(); + + private Map createDecoderMap() { + + Map tempMappingFunctions = new HashMap<>(); + tempMappingFunctions.put(ClusterShardNodeInfo.ID, STRING); + tempMappingFunctions.put(ClusterShardNodeInfo.ENDPOINT, STRING); + tempMappingFunctions.put(ClusterShardNodeInfo.IP, STRING); + tempMappingFunctions.put(ClusterShardNodeInfo.HOSTNAME, STRING); + tempMappingFunctions.put(ClusterShardNodeInfo.PORT, LONG); + tempMappingFunctions.put(ClusterShardNodeInfo.TLS_PORT, LONG); + tempMappingFunctions.put(ClusterShardNodeInfo.ROLE, STRING); + tempMappingFunctions.put(ClusterShardNodeInfo.REPLICATION_OFFSET, LONG); + tempMappingFunctions.put(ClusterShardNodeInfo.HEALTH, STRING); + + return tempMappingFunctions; + } + + @Override + @SuppressWarnings("unchecked") + public List build(Object data) { + if (null == data) { + return null; + } + + List response = new ArrayList<>(); + + List clusterShardNodeInfos = (List) data; + for (Object clusterShardNodeInfoObject : clusterShardNodeInfos) { + List clusterShardNodeInfo = (List) clusterShardNodeInfoObject; + Iterator iterator = clusterShardNodeInfo.iterator(); + response.add(new ClusterShardNodeInfo(createMapFromDecodingFunctions(iterator, mappingFunctions))); + } + + return response; + } + + @Override + public String toString() { + return "List"; + } + }; + + public static final Builder> CLUSTER_SHARD_INFO_LIST + = new Builder>() { + + final Map mappingFunctions = createDecoderMap(); + + private Map createDecoderMap() { + + Map tempMappingFunctions = new HashMap<>(); + tempMappingFunctions.put(ClusterShardInfo.SLOTS, CLUSTER_SHARD_SLOTS_RANGES); + tempMappingFunctions.put(ClusterShardInfo.NODES, CLUSTER_SHARD_NODE_INFO_LIST); + + return tempMappingFunctions; + } + + @Override + @SuppressWarnings("unchecked") + public List build(Object data) { + if (null == data) { + return null; + } + + List response = new ArrayList<>(); + + List clusterShardInfos = (List) data; + for (Object clusterShardInfoObject : clusterShardInfos) { + List clusterShardInfo = (List) clusterShardInfoObject; + Iterator iterator = clusterShardInfo.iterator(); + response.add(new ClusterShardInfo(createMapFromDecodingFunctions(iterator, mappingFunctions))); + } + + return response; + } + + @Override + public String toString() { + return "List"; + } + }; + public static final Builder> MODULE_LIST = new Builder>() { @Override public List build(Object data) { @@ -1821,13 +1970,11 @@ public String toString() { } }; - public static final Builder> LIBRARY_LIST = new Builder>() { - @Override - public List build(Object data) { - List list = (List) data; - return list.stream().map(o -> LibraryInfo.LIBRARY_BUILDER.build(o)).collect(Collectors.toList()); - } - }; + /** + * @deprecated Use {@link LibraryInfo#LIBRARY_INFO_LIST}. + */ + @Deprecated + public static final Builder> LIBRARY_LIST = LibraryInfo.LIBRARY_INFO_LIST; public static final Builder>> STRING_LIST_LIST = new Builder>>() { @Override diff --git a/src/main/java/redis/clients/jedis/ClientSetInfoConfig.java b/src/main/java/redis/clients/jedis/ClientSetInfoConfig.java new file mode 100644 index 0000000000..c1d804b28a --- /dev/null +++ b/src/main/java/redis/clients/jedis/ClientSetInfoConfig.java @@ -0,0 +1,70 @@ +package redis.clients.jedis; + +import java.util.Arrays; +import java.util.HashSet; +import redis.clients.jedis.exceptions.JedisValidationException; + +public final class ClientSetInfoConfig { + + private final boolean disabled; + + private final String libNameSuffix; + + public ClientSetInfoConfig() { + this(false, null); + } + + public ClientSetInfoConfig(boolean disabled) { + this(disabled, null); + } + + /** + * @param libNameSuffix must not have braces ({@code ()[]{}}) and spaces will be replaced with hyphens + */ + public ClientSetInfoConfig(String libNameSuffix) { + this(false, libNameSuffix); + } + + private ClientSetInfoConfig(boolean disabled, String libNameSuffix) { + this.disabled = disabled; + this.libNameSuffix = validateLibNameSuffix(libNameSuffix); + } + + private static final HashSet BRACES = new HashSet<>(Arrays.asList('(', ')', '[', ']', '{', '}')); + + private static String validateLibNameSuffix(String suffix) { + if (suffix == null || suffix.trim().isEmpty()) { + return null; + } + + for (int i = 0; i < suffix.length(); i++) { + char c = suffix.charAt(i); + if (c < ' ' || c > '~' || BRACES.contains(c)) { + throw new JedisValidationException("lib-name suffix cannot contain braces, newlines or " + + "special characters."); + } + } + + return suffix.replaceAll("\\s", "-"); + } + + public final boolean isDisabled() { + return disabled; + } + + public final String getLibNameSuffix() { + return libNameSuffix; + } + + public static final ClientSetInfoConfig DEFAULT = new ClientSetInfoConfig(); + + public static final ClientSetInfoConfig DISABLED = new ClientSetInfoConfig(true); + + /** + * @param suffix must not have braces ({@code ()[]{}}) and spaces will be replaced with hyphens + * @return config + */ + public static ClientSetInfoConfig withLibNameSuffix(String suffix) { + return new ClientSetInfoConfig(suffix); + } +} diff --git a/src/main/java/redis/clients/jedis/ClusterPipeline.java b/src/main/java/redis/clients/jedis/ClusterPipeline.java index e70db767f9..0c850c8ed8 100644 --- a/src/main/java/redis/clients/jedis/ClusterPipeline.java +++ b/src/main/java/redis/clients/jedis/ClusterPipeline.java @@ -1,5 +1,6 @@ package redis.clients.jedis; +import java.time.Duration; import java.util.Set; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import redis.clients.jedis.providers.ClusterConnectionProvider; @@ -23,6 +24,13 @@ public ClusterPipeline(Set clusterNodes, JedisClientConfig clientCo this.closeable = this.provider; } + public ClusterPipeline(Set clusterNodes, JedisClientConfig clientConfig, + GenericObjectPoolConfig poolConfig, Duration topologyRefreshPeriod) { + this(new ClusterConnectionProvider(clusterNodes, clientConfig, poolConfig, topologyRefreshPeriod), + createClusterCommandObjects(clientConfig.getRedisProtocol())); + this.closeable = this.provider; + } + public ClusterPipeline(ClusterConnectionProvider provider) { this(provider, new ClusterCommandObjects()); } diff --git a/src/main/java/redis/clients/jedis/CommandArguments.java b/src/main/java/redis/clients/jedis/CommandArguments.java index 77793fc378..b9190245ce 100644 --- a/src/main/java/redis/clients/jedis/CommandArguments.java +++ b/src/main/java/redis/clients/jedis/CommandArguments.java @@ -3,10 +3,12 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; + import redis.clients.jedis.args.Rawable; import redis.clients.jedis.args.RawableFactory; import redis.clients.jedis.commands.ProtocolCommand; import redis.clients.jedis.params.IParams; +import redis.clients.jedis.search.RediSearchUtil; public class CommandArguments implements Iterable { @@ -34,10 +36,19 @@ public CommandArguments add(Object arg) { args.add((Rawable) arg); } else if (arg instanceof byte[]) { args.add(RawableFactory.from((byte[]) arg)); + } else if (arg instanceof Integer) { + args.add(RawableFactory.from((Integer) arg)); + } else if (arg instanceof Double) { + args.add(RawableFactory.from((Double) arg)); + } else if (arg instanceof Boolean) { + args.add(RawableFactory.from((Boolean) arg ? 1 : 0)); + } else if (arg instanceof float[]) { + args.add(RawableFactory.from(RediSearchUtil.toByteArray((float[]) arg))); } else if (arg instanceof String) { args.add(RawableFactory.from((String) arg)); - } else if (arg instanceof Boolean) { - args.add(RawableFactory.from(Integer.toString((Boolean) arg ? 1 : 0))); + } else if (arg instanceof GeoCoordinate) { + GeoCoordinate geo = (GeoCoordinate) arg; + args.add(RawableFactory.from(geo.getLongitude() + "," + geo.getLatitude())); } else { args.add(RawableFactory.from(String.valueOf(arg))); } @@ -82,6 +93,11 @@ public final CommandArguments keys(Object... keys) { return this; } + public final CommandArguments keys(Collection keys) { + keys.forEach(key -> key(key)); + return this; + } + public final CommandArguments addParams(IParams params) { params.addParams(this); return this; diff --git a/src/main/java/redis/clients/jedis/CommandObjects.java b/src/main/java/redis/clients/jedis/CommandObjects.java index 14b042f3a1..2f5e4d16a0 100644 --- a/src/main/java/redis/clients/jedis/CommandObjects.java +++ b/src/main/java/redis/clients/jedis/CommandObjects.java @@ -16,6 +16,9 @@ import redis.clients.jedis.bloom.*; import redis.clients.jedis.bloom.RedisBloomProtocol.*; import redis.clients.jedis.commands.ProtocolCommand; +import redis.clients.jedis.gears.*; +import redis.clients.jedis.gears.RedisGearsProtocol.*; +import redis.clients.jedis.gears.resps.GearsLibraryInfo; import redis.clients.jedis.graph.GraphProtocol.*; import redis.clients.jedis.json.*; import redis.clients.jedis.json.JsonProtocol.JsonCommand; @@ -37,10 +40,12 @@ public class CommandObjects { private RedisProtocol protocol; - protected void setProtocol(RedisProtocol proto) { + // TODO: restrict? + public final void setProtocol(RedisProtocol proto) { this.protocol = proto; } + // TODO: remove? protected RedisProtocol getProtocol() { return protocol; } @@ -1123,6 +1128,10 @@ public final CommandObject>> hscan(String k return new CommandObject<>(commandArguments(HSCAN).key(key).add(cursor).addParams(params), BuilderFactory.HSCAN_RESPONSE); } + public final CommandObject> hscanNoValues(String key, String cursor, ScanParams params) { + return new CommandObject<>(commandArguments(HSCAN).key(key).add(cursor).addParams(params).add(NOVALUES), BuilderFactory.SCAN_RESPONSE); + } + public final CommandObject hstrlen(String key, String field) { return new CommandObject<>(commandArguments(HSTRLEN).key(key).add(field), BuilderFactory.LONG); } @@ -1131,6 +1140,10 @@ public final CommandObject>> hscan(byte[] k return new CommandObject<>(commandArguments(HSCAN).key(key).add(cursor).addParams(params), BuilderFactory.HSCAN_BINARY_RESPONSE); } + public final CommandObject> hscanNoValues(byte[] key, byte[] cursor, ScanParams params) { + return new CommandObject<>(commandArguments(HSCAN).key(key).add(cursor).addParams(params).add(NOVALUES), BuilderFactory.SCAN_BINARY_RESPONSE); + } + public final CommandObject hstrlen(byte[] key, byte[] field) { return new CommandObject<>(commandArguments(HSTRLEN).key(key).add(field), BuilderFactory.LONG); } @@ -2399,24 +2412,24 @@ public final CommandObject> xrevrange(String key, String end, return new CommandObject<>(commandArguments(XREVRANGE).key(key).add(end).add(start).add(COUNT).add(count), BuilderFactory.STREAM_ENTRY_LIST); } - public final CommandObject> xrange(byte[] key, byte[] start, byte[] end) { + public final CommandObject> xrange(byte[] key, byte[] start, byte[] end) { return new CommandObject<>(commandArguments(XRANGE).key(key).add(start == null ? "-" : start).add(end == null ? "+" : end), - BuilderFactory.BINARY_LIST); + BuilderFactory.RAW_OBJECT_LIST); } - public final CommandObject> xrange(byte[] key, byte[] start, byte[] end, int count) { + public final CommandObject> xrange(byte[] key, byte[] start, byte[] end, int count) { return new CommandObject<>(commandArguments(XRANGE).key(key).add(start == null ? "-" : start).add(end == null ? "+" : end) - .add(COUNT).add(count), BuilderFactory.BINARY_LIST); + .add(COUNT).add(count), BuilderFactory.RAW_OBJECT_LIST); } - public final CommandObject> xrevrange(byte[] key, byte[] end, byte[] start) { + public final CommandObject> xrevrange(byte[] key, byte[] end, byte[] start) { return new CommandObject<>(commandArguments(XREVRANGE).key(key).add(end == null ? "+" : end).add(start == null ? "-" : start), - BuilderFactory.BINARY_LIST); + BuilderFactory.RAW_OBJECT_LIST); } - public final CommandObject> xrevrange(byte[] key, byte[] end, byte[] start, int count) { + public final CommandObject> xrevrange(byte[] key, byte[] end, byte[] start, int count) { return new CommandObject<>(commandArguments(XREVRANGE).key(key).add(end == null ? "+" : end).add(start == null ? "-" : start) - .add(COUNT).add(count), BuilderFactory.BINARY_LIST); + .add(COUNT).add(count), BuilderFactory.RAW_OBJECT_LIST); } public final CommandObject xack(String key, String group, StreamEntryID... ids) { @@ -2657,7 +2670,7 @@ public final CommandObject>>> xreadGrou return new CommandObject<>(args, BuilderFactory.STREAM_READ_RESPONSE); } - public final CommandObject> xread(XReadParams xReadParams, Map.Entry... streams) { + public final CommandObject> xread(XReadParams xReadParams, Map.Entry... streams) { CommandArguments args = commandArguments(XREAD).addParams(xReadParams).add(STREAMS); for (Map.Entry entry : streams) { args.key(entry.getKey()); @@ -2665,10 +2678,10 @@ public final CommandObject> xread(XReadParams xReadParams, Map.Entr for (Map.Entry entry : streams) { args.add(entry.getValue()); } - return new CommandObject<>(args, BuilderFactory.BINARY_LIST); + return new CommandObject<>(args, BuilderFactory.RAW_OBJECT_LIST); } - public final CommandObject> xreadGroup(byte[] groupName, byte[] consumer, + public final CommandObject> xreadGroup(byte[] groupName, byte[] consumer, XReadGroupParams xReadGroupParams, Map.Entry... streams) { CommandArguments args = commandArguments(XREADGROUP) .add(GROUP).add(groupName).add(consumer) @@ -2679,39 +2692,33 @@ public final CommandObject> xreadGroup(byte[] groupName, byte[] con for (Map.Entry entry : streams) { args.add(entry.getValue()); } - return new CommandObject<>(args, BuilderFactory.BINARY_LIST); + return new CommandObject<>(args, BuilderFactory.RAW_OBJECT_LIST); } // Stream commands // Scripting commands public final CommandObject eval(String script) { - return new CommandObject<>(commandArguments(EVAL).add(script).add(0), BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(EVAL).add(script).add(0), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject eval(String script, String sampleKey) { - return new CommandObject<>(commandArguments(EVAL).add(script).add(0).processKey(sampleKey), BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(EVAL).add(script).add(0).processKey(sampleKey), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject eval(String script, int keyCount, String... params) { return new CommandObject<>(commandArguments(EVAL).add(script).add(keyCount) .addObjects((Object[]) params).processKeys(Arrays.copyOf(params, keyCount)), - BuilderFactory.ENCODED_OBJECT); + BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject eval(String script, List keys, List args) { - String[] keysArray = keys.toArray(new String[keys.size()]); - String[] argsArray = args.toArray(new String[args.size()]); - return new CommandObject<>(commandArguments(EVAL).add(script).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(EVAL).add(script).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject evalReadonly(String script, List keys, List args) { - String[] keysArray = keys.toArray(new String[keys.size()]); - String[] argsArray = args.toArray(new String[args.size()]); - return new CommandObject<>(commandArguments(EVAL_RO).add(script).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(EVAL_RO).add(script).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject eval(byte[] script) { @@ -2729,49 +2736,37 @@ public final CommandObject eval(byte[] script, int keyCount, byte[]... p } public final CommandObject eval(byte[] script, List keys, List args) { - byte[][] keysArray = keys.toArray(new byte[keys.size()][]); - byte[][] argsArray = args.toArray(new byte[args.size()][]); - return new CommandObject<>(commandArguments(EVAL).add(script).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.RAW_OBJECT); + return new CommandObject<>(commandArguments(EVAL).add(script).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.RAW_OBJECT); } public final CommandObject evalReadonly(byte[] script, List keys, List args) { - byte[][] keysArray = keys.toArray(new byte[keys.size()][]); - byte[][] argsArray = args.toArray(new byte[args.size()][]); - return new CommandObject<>(commandArguments(EVAL_RO).add(script).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.RAW_OBJECT); + return new CommandObject<>(commandArguments(EVAL_RO).add(script).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.RAW_OBJECT); } public final CommandObject evalsha(String sha1) { - return new CommandObject<>(commandArguments(EVALSHA).add(sha1).add(0), BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(EVALSHA).add(sha1).add(0), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject evalsha(String sha1, String sampleKey) { - return new CommandObject<>(commandArguments(EVALSHA).add(sha1).add(0).processKey(sampleKey), BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(EVALSHA).add(sha1).add(0).processKey(sampleKey), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject evalsha(String sha1, int keyCount, String... params) { return new CommandObject<>(commandArguments(EVALSHA).add(sha1).add(keyCount) .addObjects((Object[]) params).processKeys(Arrays.copyOf(params, keyCount)), - BuilderFactory.ENCODED_OBJECT); + BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject evalsha(String sha1, List keys, List args) { - String[] keysArray = keys.toArray(new String[keys.size()]); - String[] argsArray = args.toArray(new String[args.size()]); - return new CommandObject<>(commandArguments(EVALSHA).add(sha1).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(EVALSHA).add(sha1).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject evalshaReadonly(String sha1, List keys, List args) { - String[] keysArray = keys.toArray(new String[keys.size()]); - String[] argsArray = args.toArray(new String[args.size()]); - return new CommandObject<>(commandArguments(EVALSHA_RO).add(sha1).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(EVALSHA_RO).add(sha1).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject evalsha(byte[] sha1) { @@ -2789,19 +2784,13 @@ public final CommandObject evalsha(byte[] sha1, int keyCount, byte[]... } public final CommandObject evalsha(byte[] sha1, List keys, List args) { - byte[][] keysArray = keys.toArray(new byte[keys.size()][]); - byte[][] argsArray = args.toArray(new byte[args.size()][]); - return new CommandObject<>(commandArguments(EVALSHA).add(sha1).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.RAW_OBJECT); + return new CommandObject<>(commandArguments(EVALSHA).add(sha1).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.RAW_OBJECT); } public final CommandObject evalshaReadonly(byte[] sha1, List keys, List args) { - byte[][] keysArray = keys.toArray(new byte[keys.size()][]); - byte[][] argsArray = args.toArray(new byte[args.size()][]); - return new CommandObject<>(commandArguments(EVALSHA_RO).add(sha1).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.RAW_OBJECT); + return new CommandObject<>(commandArguments(EVALSHA_RO).add(sha1).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.RAW_OBJECT); } public final CommandObject> scriptExists(List sha1s) { @@ -2866,26 +2855,21 @@ public final CommandObject scriptKill(byte[] sampleKey) { return new CommandObject<>(commandArguments(SCRIPT).add(KILL).processKey(sampleKey), BuilderFactory.STRING); } - private final CommandObject SLOWLOG_RESET_COMMAND_OBJECT = new CommandObject<>(commandArguments(SLOWLOG).add(RESET), BuilderFactory.STRING); + private final CommandObject SLOWLOG_RESET_COMMAND_OBJECT + = new CommandObject<>(commandArguments(SLOWLOG).add(Keyword.RESET), BuilderFactory.STRING); public final CommandObject slowlogReset() { return SLOWLOG_RESET_COMMAND_OBJECT; } public final CommandObject fcall(String name, List keys, List args) { - String[] keysArray = keys.toArray(new String[keys.size()]); - String[] argsArray = args.toArray(new String[args.size()]); - return new CommandObject<>(commandArguments(FCALL).add(name).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(FCALL).add(name).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject fcallReadonly(String name, List keys, List args) { - String[] keysArray = keys.toArray(new String[keys.size()]); - String[] argsArray = args.toArray(new String[args.size()]); - return new CommandObject<>(commandArguments(FCALL_RO).add(name).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.ENCODED_OBJECT); + return new CommandObject<>(commandArguments(FCALL_RO).add(name).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); } public final CommandObject functionDelete(String libraryName) { @@ -2893,21 +2877,21 @@ public final CommandObject functionDelete(String libraryName) { } public final CommandObject> functionList() { - return new CommandObject<>(commandArguments(FUNCTION).add(LIST), BuilderFactory.LIBRARY_LIST); + return new CommandObject<>(commandArguments(FUNCTION).add(LIST), LibraryInfo.LIBRARY_INFO_LIST); } public final CommandObject> functionList(String libraryNamePattern) { return new CommandObject<>(commandArguments(FUNCTION).add(LIST).add(LIBRARYNAME) - .add(libraryNamePattern), BuilderFactory.LIBRARY_LIST); + .add(libraryNamePattern), LibraryInfo.LIBRARY_INFO_LIST); } public final CommandObject> functionListWithCode() { - return new CommandObject<>(commandArguments(FUNCTION).add(LIST).add(WITHCODE), BuilderFactory.LIBRARY_LIST); + return new CommandObject<>(commandArguments(FUNCTION).add(LIST).add(WITHCODE), LibraryInfo.LIBRARY_INFO_LIST); } public final CommandObject> functionListWithCode(String libraryNamePattern) { return new CommandObject<>(commandArguments(FUNCTION).add(LIST).add(LIBRARYNAME) - .add(libraryNamePattern).add(WITHCODE), BuilderFactory.LIBRARY_LIST); + .add(libraryNamePattern).add(WITHCODE), LibraryInfo.LIBRARY_INFO_LIST); } public final CommandObject functionLoad(String functionCode) { @@ -2939,19 +2923,13 @@ public final CommandObject functionKill() { } public final CommandObject fcall(byte[] name, List keys, List args) { - byte[][] keysArray = keys.toArray(new byte[keys.size()][]); - byte[][] argsArray = args.toArray(new byte[args.size()][]); - return new CommandObject<>(commandArguments(FCALL).add(name).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.RAW_OBJECT); + return new CommandObject<>(commandArguments(FCALL).add(name).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.RAW_OBJECT); } public final CommandObject fcallReadonly(byte[] name, List keys, List args) { - byte[][] keysArray = keys.toArray(new byte[keys.size()][]); - byte[][] argsArray = args.toArray(new byte[args.size()][]); - return new CommandObject<>(commandArguments(FCALL_RO).add(name).add(keysArray.length) - .keys((Object[]) keysArray).addObjects((Object[]) argsArray), - BuilderFactory.RAW_OBJECT); + return new CommandObject<>(commandArguments(FCALL_RO).add(name).add(keys.size()) + .keys(keys).addObjects(args), BuilderFactory.RAW_OBJECT); } public final CommandObject functionDelete(byte[] libraryName) { @@ -3142,6 +3120,14 @@ public final CommandObject spublish(byte[] channel, byte[] message) { // Miscellaneous commands // RediSearch commands + public final CommandObject hsetObject(String key, String field, Object value) { + return new CommandObject<>(commandArguments(HSET).key(key).add(field).add(value), BuilderFactory.LONG); + } + + public final CommandObject hsetObject(String key, Map hash) { + return new CommandObject<>(addFlatMapArgs(commandArguments(HSET).key(key), hash), BuilderFactory.LONG); + } + private boolean isRoundRobinSearchCommand() { if (broadcastAndRoundRobinConfig == null) { return true; @@ -3151,8 +3137,24 @@ private boolean isRoundRobinSearchCommand() { return true; } - private CommandArguments checkAndRoundRobinSearchCommand(CommandArguments commandArguments, String indexName) { - return isRoundRobinSearchCommand() ? commandArguments.add(indexName) : commandArguments.key(indexName); + private CommandArguments checkAndRoundRobinSearchCommand(SearchCommand sc, String idx) { + CommandArguments ca = commandArguments(sc); + if (isRoundRobinSearchCommand()) { + ca.add(idx); + } else { + ca.key(idx); + } + return ca; + } + + private CommandArguments checkAndRoundRobinSearchCommand(SearchCommand sc, String idx1, String idx2) { + CommandArguments ca = commandArguments(sc); + if (isRoundRobinSearchCommand()) { + ca.add(idx1).add(idx2); + } else { + ca.key(idx1).key(idx2); + } + return ca; } private CommandArguments checkAndRoundRobinSearchCommand(CommandArguments commandArguments, byte[] indexName) { @@ -3165,7 +3167,7 @@ private CommandObject directSearchCommand(CommandObject object, String } public final CommandObject ftCreate(String indexName, IndexOptions indexOptions, Schema schema) { - CommandArguments args = commandArguments(SearchCommand.CREATE).add(indexName) + CommandArguments args = checkAndRoundRobinSearchCommand(SearchCommand.CREATE, indexName) .addParams(indexOptions).add(SearchKeyword.SCHEMA); schema.fields.forEach(field -> args.addParams(field)); return new CommandObject<>(args, BuilderFactory.STRING); @@ -3173,39 +3175,60 @@ public final CommandObject ftCreate(String indexName, IndexOptions index public final CommandObject ftCreate(String indexName, FTCreateParams createParams, Iterable schemaFields) { - CommandArguments args = commandArguments(SearchCommand.CREATE).add(indexName) + CommandArguments args = checkAndRoundRobinSearchCommand(SearchCommand.CREATE, indexName) .addParams(createParams).add(SearchKeyword.SCHEMA); schemaFields.forEach(field -> args.addParams(field)); return new CommandObject<>(args, BuilderFactory.STRING); } public final CommandObject ftAlter(String indexName, Schema schema) { - CommandArguments args = commandArguments(SearchCommand.ALTER).add(indexName) + CommandArguments args = checkAndRoundRobinSearchCommand(SearchCommand.ALTER, indexName) .add(SearchKeyword.SCHEMA).add(SearchKeyword.ADD); schema.fields.forEach(field -> args.addParams(field)); return new CommandObject<>(args, BuilderFactory.STRING); } public final CommandObject ftAlter(String indexName, Iterable schemaFields) { - CommandArguments args = commandArguments(SearchCommand.ALTER).add(indexName) + CommandArguments args = checkAndRoundRobinSearchCommand(SearchCommand.ALTER, indexName) .add(SearchKeyword.SCHEMA).add(SearchKeyword.ADD); schemaFields.forEach(field -> args.addParams(field)); return new CommandObject<>(args, BuilderFactory.STRING); } + public final CommandObject ftAliasAdd(String aliasName, String indexName) { + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.ALIASADD, aliasName, indexName), BuilderFactory.STRING); + } + + public final CommandObject ftAliasUpdate(String aliasName, String indexName) { + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.ALIASUPDATE, aliasName, indexName), BuilderFactory.STRING); + } + + public final CommandObject ftAliasDel(String aliasName) { + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.ALIASDEL, aliasName), BuilderFactory.STRING); + } + + public final CommandObject ftDropIndex(String indexName) { + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.DROPINDEX, indexName), BuilderFactory.STRING); + } + + public final CommandObject ftDropIndexDD(String indexName) { + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.DROPINDEX, indexName).add(SearchKeyword.DD), + BuilderFactory.STRING); + } + public final CommandObject ftSearch(String indexName, String query) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.SEARCH), indexName).add(query), + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.SEARCH, indexName).add(query), getSearchResultBuilder(() -> new SearchResultBuilder(true, false, true))); } public final CommandObject ftSearch(String indexName, String query, FTSearchParams params) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.SEARCH), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.SEARCH, indexName) .add(query).addParams(params.dialectOptional(searchDialect.get())), getSearchResultBuilder(() -> new SearchResultBuilder(!params.getNoContent(), params.getWithScores(), true))); } public final CommandObject ftSearch(String indexName, Query query) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.SEARCH), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.SEARCH, indexName) .addParams(query.dialectOptional(searchDialect.get())), getSearchResultBuilder(() -> new SearchResultBuilder(!query.getNoContent(), query.getWithScores(), true))); } @@ -3221,35 +3244,35 @@ public final CommandObject ftSearch(byte[] indexName, Query query) } public final CommandObject ftExplain(String indexName, Query query) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.EXPLAIN), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.EXPLAIN, indexName) .addParams(query.dialectOptional(searchDialect.get())), BuilderFactory.STRING); } public final CommandObject> ftExplainCLI(String indexName, Query query) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.EXPLAINCLI), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.EXPLAINCLI, indexName) .addParams(query.dialectOptional(searchDialect.get())), BuilderFactory.STRING_LIST); } public final CommandObject ftAggregate(String indexName, AggregationBuilder aggr) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.AGGREGATE), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.AGGREGATE, indexName) .addParams(aggr.dialectOptional(searchDialect.get())), !aggr.isWithCursor() ? AggregationResult.SEARCH_AGGREGATION_RESULT : AggregationResult.SEARCH_AGGREGATION_RESULT_WITH_CURSOR); } public final CommandObject ftCursorRead(String indexName, long cursorId, int count) { return new CommandObject<>(commandArguments(SearchCommand.CURSOR).add(SearchKeyword.READ) - .add(indexName).add(cursorId).add(SearchKeyword.COUNT).add(count), + .key(indexName).add(cursorId).add(SearchKeyword.COUNT).add(count), AggregationResult.SEARCH_AGGREGATION_RESULT_WITH_CURSOR); } public final CommandObject ftCursorDel(String indexName, long cursorId) { return new CommandObject<>(commandArguments(SearchCommand.CURSOR).add(SearchKeyword.DEL) - .add(indexName).add(cursorId), BuilderFactory.STRING); + .key(indexName).add(cursorId), BuilderFactory.STRING); } public final CommandObject>> ftProfileAggregate( String indexName, FTProfileParams profileParams, AggregationBuilder aggr) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.PROFILE), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.PROFILE, indexName) .add(SearchKeyword.AGGREGATE).addParams(profileParams).add(SearchKeyword.QUERY) .addParams(aggr.dialectOptional(searchDialect.get())), new SearchProfileResponseBuilder<>( !aggr.isWithCursor() ? AggregationResult.SEARCH_AGGREGATION_RESULT @@ -3258,7 +3281,7 @@ public final CommandObject>> ft public final CommandObject>> ftProfileSearch( String indexName, FTProfileParams profileParams, Query query) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.PROFILE), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.PROFILE, indexName) .add(SearchKeyword.SEARCH).addParams(profileParams).add(SearchKeyword.QUERY) .addParams(query.dialectOptional(searchDialect.get())), new SearchProfileResponseBuilder<>( getSearchResultBuilder(() -> new SearchResultBuilder(!query.getNoContent(), query.getWithScores(), true)))); @@ -3266,7 +3289,7 @@ public final CommandObject>> ftProfi public final CommandObject>> ftProfileSearch( String indexName, FTProfileParams profileParams, String query, FTSearchParams searchParams) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.PROFILE), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.PROFILE, indexName) .add(SearchKeyword.SEARCH).addParams(profileParams).add(SearchKeyword.QUERY).add(query) .addParams(searchParams.dialectOptional(searchDialect.get())), new SearchProfileResponseBuilder<>( getSearchResultBuilder(() -> new SearchResultBuilder(!searchParams.getNoContent(), searchParams.getWithScores(), true)))); @@ -3277,22 +3300,13 @@ private Builder getSearchResultBuilder(Supplier ftDropIndex(String indexName) { - return new CommandObject<>(commandArguments(SearchCommand.DROPINDEX).add(indexName), BuilderFactory.STRING); - } - - public final CommandObject ftDropIndexDD(String indexName) { - return new CommandObject<>(commandArguments(SearchCommand.DROPINDEX).add(indexName).add(SearchKeyword.DD), - BuilderFactory.STRING); - } - public final CommandObject ftSynUpdate(String indexName, String synonymGroupId, String... terms) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.SYNUPDATE), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.SYNUPDATE, indexName) .add(synonymGroupId).addObjects((Object[]) terms), BuilderFactory.STRING); } public final CommandObject>> ftSynDump(String indexName) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.SYNDUMP), indexName), + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.SYNDUMP, indexName), SearchBuilderFactory.SEARCH_SYNONYM_GROUPS); } @@ -3323,38 +3337,26 @@ public final CommandObject> ftDictDumpBySampleKey(String indexName, } public final CommandObject>> ftSpellCheck(String index, String query) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.SPELLCHECK), index).add(query), + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.SPELLCHECK, index).add(query), SearchBuilderFactory.SEARCH_SPELLCHECK_RESPONSE); } public final CommandObject>> ftSpellCheck(String index, String query, FTSpellCheckParams spellCheckParams) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.SPELLCHECK), index).add(query) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.SPELLCHECK, index).add(query) .addParams(spellCheckParams.dialectOptional(searchDialect.get())), SearchBuilderFactory.SEARCH_SPELLCHECK_RESPONSE); } public final CommandObject> ftInfo(String indexName) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.INFO), indexName), + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.INFO, indexName), protocol == RedisProtocol.RESP3 ? BuilderFactory.AGGRESSIVE_ENCODED_OBJECT_MAP : BuilderFactory.ENCODED_OBJECT_MAP); } public final CommandObject> ftTagVals(String indexName, String fieldName) { - return new CommandObject<>(checkAndRoundRobinSearchCommand(commandArguments(SearchCommand.TAGVALS), indexName) + return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.TAGVALS, indexName) .add(fieldName), BuilderFactory.STRING_SET); } - public final CommandObject ftAliasAdd(String aliasName, String indexName) { - return new CommandObject<>(commandArguments(SearchCommand.ALIASADD).add(aliasName).add(indexName), BuilderFactory.STRING); - } - - public final CommandObject ftAliasUpdate(String aliasName, String indexName) { - return new CommandObject<>(commandArguments(SearchCommand.ALIASUPDATE).add(aliasName).add(indexName), BuilderFactory.STRING); - } - - public final CommandObject ftAliasDel(String aliasName) { - return new CommandObject<>(commandArguments(SearchCommand.ALIASDEL).add(aliasName), BuilderFactory.STRING); - } - public final CommandObject> ftConfigGet(String option) { return new CommandObject<>(commandArguments(SearchCommand.CONFIG).add(SearchKeyword.GET).add(option), protocol == RedisProtocol.RESP3 ? BuilderFactory.AGGRESSIVE_ENCODED_OBJECT_MAP : BuilderFactory.ENCODED_OBJECT_MAP_FROM_PAIRS); @@ -4038,11 +4040,13 @@ public final CommandObject> cfInfo(String key) { } public final CommandObject cmsInitByDim(String key, long width, long depth) { - return new CommandObject<>(commandArguments(CountMinSketchCommand.INITBYDIM).key(key).add(width).add(depth), BuilderFactory.STRING); + return new CommandObject<>(commandArguments(CountMinSketchCommand.INITBYDIM).key(key).add(width) + .add(depth), BuilderFactory.STRING); } public final CommandObject cmsInitByProb(String key, double error, double probability) { - return new CommandObject<>(commandArguments(CountMinSketchCommand.INITBYPROB).key(key).add(error).add(probability), BuilderFactory.STRING); + return new CommandObject<>(commandArguments(CountMinSketchCommand.INITBYPROB).key(key).add(error) + .add(probability), BuilderFactory.STRING); } public final CommandObject> cmsIncrBy(String key, Map itemIncrements) { @@ -4052,7 +4056,8 @@ public final CommandObject> cmsIncrBy(String key, Map i } public final CommandObject> cmsQuery(String key, String... items) { - return new CommandObject<>(commandArguments(CountMinSketchCommand.QUERY).key(key).addObjects((Object[]) items), BuilderFactory.LONG_LIST); + return new CommandObject<>(commandArguments(CountMinSketchCommand.QUERY).key(key) + .addObjects((Object[]) items), BuilderFactory.LONG_LIST); } public final CommandObject cmsMerge(String destKey, String... keys) { @@ -4218,6 +4223,33 @@ public final CommandObject> graphConfigGet(String configName } // RedisGraph commands + // RedisGears commands + public final CommandObject tFunctionLoad(String libraryCode, TFunctionLoadParams params) { + return new CommandObject<>(commandArguments(GearsCommand.TFUNCTION).add(GearsKeyword.LOAD) + .addParams(params).add(libraryCode), BuilderFactory.STRING); + } + + public final CommandObject tFunctionDelete(String libraryName) { + return new CommandObject<>(commandArguments(GearsCommand.TFUNCTION).add(GearsKeyword.DELETE) + .add(libraryName), BuilderFactory.STRING); + } + + public final CommandObject> tFunctionList(TFunctionListParams params) { + return new CommandObject<>(commandArguments(GearsCommand.TFUNCTION).add(GearsKeyword.LIST) + .addParams(params), GearsLibraryInfo.GEARS_LIBRARY_INFO_LIST); + } + + public final CommandObject tFunctionCall(String library, String function, List keys, List args) { + return new CommandObject<>(commandArguments(GearsCommand.TFCALL).add(library + "." + function) + .add(keys.size()).keys(keys).addObjects(args), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); + } + + public final CommandObject tFunctionCallAsync(String library, String function, List keys, List args) { + return new CommandObject<>(commandArguments(GearsCommand.TFCALLASYNC).add(library + "." + function) + .add(keys.size()).keys(keys).addObjects(args), BuilderFactory.AGGRESSIVE_ENCODED_OBJECT); + } + // RedisGears commands + /** * Get the instance for JsonObjectMapper if not null, otherwise a new instance reference with * default implementation will be created and returned. diff --git a/src/main/java/redis/clients/jedis/Connection.java b/src/main/java/redis/clients/jedis/Connection.java index 9cdbfdbd7c..50243e20d7 100644 --- a/src/main/java/redis/clients/jedis/Connection.java +++ b/src/main/java/redis/clients/jedis/Connection.java @@ -23,7 +23,6 @@ import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.exceptions.JedisValidationException; import redis.clients.jedis.util.IOUtils; -import redis.clients.jedis.util.JedisMetaInfo; import redis.clients.jedis.util.RedisInputStream; import redis.clients.jedis.util.RedisOutputStream; @@ -73,7 +72,7 @@ public String toString() { return "Connection{" + socketFactory + "}"; } - final RedisProtocol getRedisProtocol() { + public final RedisProtocol getRedisProtocol() { return protocol; } @@ -388,7 +387,7 @@ private static boolean validateClientInfo(String info) { return true; } - private void initializeFromClientConfig(JedisClientConfig config) { + private void initializeFromClientConfig(final JedisClientConfig config) { try { connect(); @@ -415,16 +414,25 @@ private void initializeFromClientConfig(JedisClientConfig config) { fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETNAME).add(clientName)); } - String libName = JedisMetaInfo.getArtifactId(); - if (libName != null && validateClientInfo(libName)) { - fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETINFO) - .add(ClientAttributeOption.LIB_NAME.getRaw()).add(libName)); - } + ClientSetInfoConfig setInfoConfig = config.getClientSetInfoConfig(); + if (setInfoConfig == null) setInfoConfig = ClientSetInfoConfig.DEFAULT; + + if (!setInfoConfig.isDisabled()) { + String libName = JedisMetaInfo.getArtifactId(); + if (libName != null && validateClientInfo(libName)) { + String libNameSuffix = setInfoConfig.getLibNameSuffix(); + if (libNameSuffix != null) { // validation is moved into ClientSetInfoConfig constructor + libName = libName + '(' + libNameSuffix + ')'; + } + fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETINFO) + .add(ClientAttributeOption.LIB_NAME.getRaw()).add(libName)); + } - String libVersion = JedisMetaInfo.getVersion(); - if (libVersion != null && validateClientInfo(libVersion)) { - fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETINFO) - .add(ClientAttributeOption.LIB_VER.getRaw()).add(libVersion)); + String libVersion = JedisMetaInfo.getVersion(); + if (libVersion != null && validateClientInfo(libVersion)) { + fireAndForgetMsg.add(new CommandArguments(Command.CLIENT).add(Keyword.SETINFO) + .add(ClientAttributeOption.LIB_VER.getRaw()).add(libVersion)); + } } for (CommandArguments arg : fireAndForgetMsg) { diff --git a/src/main/java/redis/clients/jedis/ConnectionFactory.java b/src/main/java/redis/clients/jedis/ConnectionFactory.java index d286462347..3500a21172 100644 --- a/src/main/java/redis/clients/jedis/ConnectionFactory.java +++ b/src/main/java/redis/clients/jedis/ConnectionFactory.java @@ -76,7 +76,7 @@ public boolean validateObject(PooledObject pooledConnection) { // check HostAndPort ?? return jedis.isConnected() && jedis.ping(); } catch (final Exception e) { - logger.error("Error while validating pooled Connection object.", e); + logger.warn("Error while validating pooled Connection object.", e); return false; } } diff --git a/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java b/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java index 5f0b4866f1..6d62646a5e 100644 --- a/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java +++ b/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java @@ -24,10 +24,13 @@ public final class DefaultJedisClientConfig implements JedisClientConfig { private final HostAndPortMapper hostAndPortMapper; + private final ClientSetInfoConfig clientSetInfoConfig; + private DefaultJedisClientConfig(RedisProtocol protocol, int connectionTimeoutMillis, int soTimeoutMillis, int blockingSocketTimeoutMillis, Supplier credentialsProvider, int database, String clientName, boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters, - HostnameVerifier hostnameVerifier, HostAndPortMapper hostAndPortMapper) { + HostnameVerifier hostnameVerifier, HostAndPortMapper hostAndPortMapper, + ClientSetInfoConfig clientSetInfoConfig) { this.redisProtocol = protocol; this.connectionTimeoutMillis = connectionTimeoutMillis; this.socketTimeoutMillis = soTimeoutMillis; @@ -40,6 +43,7 @@ private DefaultJedisClientConfig(RedisProtocol protocol, int connectionTimeoutMi this.sslParameters = sslParameters; this.hostnameVerifier = hostnameVerifier; this.hostAndPortMapper = hostAndPortMapper; + this.clientSetInfoConfig = clientSetInfoConfig; } @Override @@ -113,6 +117,11 @@ public HostAndPortMapper getHostAndPortMapper() { return hostAndPortMapper; } + @Override + public ClientSetInfoConfig getClientSetInfoConfig() { + return clientSetInfoConfig; + } + public static Builder builder() { return new Builder(); } @@ -138,6 +147,8 @@ public static class Builder { private HostAndPortMapper hostAndPortMapper = null; + private ClientSetInfoConfig clientSetInfoConfig = ClientSetInfoConfig.DEFAULT; + private Builder() { } @@ -149,7 +160,7 @@ public DefaultJedisClientConfig build() { return new DefaultJedisClientConfig(redisProtocol, connectionTimeoutMillis, socketTimeoutMillis, blockingSocketTimeoutMillis, credentialsProvider, database, clientName, ssl, - sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper); + sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper, clientSetInfoConfig); } /** @@ -239,6 +250,11 @@ public Builder hostAndPortMapper(HostAndPortMapper hostAndPortMapper) { this.hostAndPortMapper = hostAndPortMapper; return this; } + + public Builder clientSetInfoConfig(ClientSetInfoConfig setInfoConfig) { + this.clientSetInfoConfig = setInfoConfig; + return this; + } } public static DefaultJedisClientConfig create(int connectionTimeoutMillis, int soTimeoutMillis, @@ -248,7 +264,7 @@ public static DefaultJedisClientConfig create(int connectionTimeoutMillis, int s return new DefaultJedisClientConfig(null, connectionTimeoutMillis, soTimeoutMillis, blockingSocketTimeoutMillis, new DefaultRedisCredentialsProvider(new DefaultRedisCredentials(user, password)), database, - clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper); + clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper, null); } public static DefaultJedisClientConfig copyConfig(JedisClientConfig copy) { @@ -256,6 +272,7 @@ public static DefaultJedisClientConfig copyConfig(JedisClientConfig copy) { copy.getConnectionTimeoutMillis(), copy.getSocketTimeoutMillis(), copy.getBlockingSocketTimeoutMillis(), copy.getCredentialsProvider(), copy.getDatabase(), copy.getClientName(), copy.isSsl(), copy.getSslSocketFactory(), - copy.getSslParameters(), copy.getHostnameVerifier(), copy.getHostAndPortMapper()); + copy.getSslParameters(), copy.getHostnameVerifier(), copy.getHostAndPortMapper(), + copy.getClientSetInfoConfig()); } } diff --git a/src/main/java/redis/clients/jedis/DefaultJedisSocketFactory.java b/src/main/java/redis/clients/jedis/DefaultJedisSocketFactory.java index f9c7cd2228..a2d963e221 100644 --- a/src/main/java/redis/clients/jedis/DefaultJedisSocketFactory.java +++ b/src/main/java/redis/clients/jedis/DefaultJedisSocketFactory.java @@ -70,7 +70,9 @@ private Socket connectToFirstSuccessfulHost(HostAndPort hostAndPort) throws Exce socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to ensure timely delivery of data socket.setSoLinger(true, 0); // Control calls close () method, the underlying socket is closed immediately - socket.connect(new InetSocketAddress(host.getHostAddress(), hostAndPort.getPort()), connectionTimeout); + // Passing 'host' directly will avoid another call to InetAddress.getByName() inside the InetSocketAddress constructor. + // For machines with ipv4 and ipv6, but the startNode uses ipv4 to connect, the ipv6 connection may fail. + socket.connect(new InetSocketAddress(host, hostAndPort.getPort()), connectionTimeout); return socket; } catch (Exception e) { jce.addSuppressed(e); diff --git a/src/main/java/redis/clients/jedis/Jedis.java b/src/main/java/redis/clients/jedis/Jedis.java index c024894caa..1e25f2ffcb 100644 --- a/src/main/java/redis/clients/jedis/Jedis.java +++ b/src/main/java/redis/clients/jedis/Jedis.java @@ -14,6 +14,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.stream.Collectors; +import java.util.Arrays; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLParameters; @@ -4412,11 +4413,6 @@ public ScanResult scan(final byte[] cursor, final ScanParams params, fin return connection.executeCommand(commandObjects.scan(cursor, params, type)); } - @Override - public ScanResult> hscan(final byte[] key, final byte[] cursor) { - return hscan(key, cursor, new ScanParams()); - } - @Override public ScanResult> hscan(final byte[] key, final byte[] cursor, final ScanParams params) { @@ -4424,6 +4420,12 @@ public ScanResult> hscan(final byte[] key, final byte[ return connection.executeCommand(commandObjects.hscan(key, cursor, params)); } + @Override + public ScanResult hscanNoValues(final byte[] key, final byte[] cursor, final ScanParams params) { + checkIsInMultiOrPipeline(); + return connection.executeCommand(commandObjects.hscanNoValues(key, cursor, params)); + } + @Override public ScanResult sscan(final byte[] key, final byte[] cursor) { return sscan(key, cursor, new ScanParams()); @@ -4646,13 +4648,13 @@ public long hstrlen(final byte[] key, final byte[] field) { } @Override - public List xread(XReadParams xReadParams, Entry... streams) { + public List xread(XReadParams xReadParams, Entry... streams) { checkIsInMultiOrPipeline(); return connection.executeCommand(commandObjects.xread(xReadParams, streams)); } @Override - public List xreadGroup(byte[] groupName, byte[] consumer, + public List xreadGroup(byte[] groupName, byte[] consumer, XReadGroupParams xReadGroupParams, Entry... streams) { checkIsInMultiOrPipeline(); return connection.executeCommand(commandObjects.xreadGroup(groupName, consumer, xReadGroupParams, streams)); @@ -4671,25 +4673,25 @@ public long xlen(byte[] key) { } @Override - public List xrange(byte[] key, byte[] start, byte[] end) { + public List xrange(byte[] key, byte[] start, byte[] end) { checkIsInMultiOrPipeline(); return connection.executeCommand(commandObjects.xrange(key, start, end)); } @Override - public List xrange(byte[] key, byte[] start, byte[] end, int count) { + public List xrange(byte[] key, byte[] start, byte[] end, int count) { checkIsInMultiOrPipeline(); return connection.executeCommand(commandObjects.xrange(key, start, end, count)); } @Override - public List xrevrange(byte[] key, byte[] end, byte[] start) { + public List xrevrange(byte[] key, byte[] end, byte[] start) { checkIsInMultiOrPipeline(); return connection.executeCommand(commandObjects.xrevrange(key, end, start)); } @Override - public List xrevrange(byte[] key, byte[] end, byte[] start, int count) { + public List xrevrange(byte[] key, byte[] end, byte[] start, int count) { checkIsInMultiOrPipeline(); return connection.executeCommand(commandObjects.xrevrange(key, end, start, count)); } @@ -6386,7 +6388,7 @@ public String srandmember(final String key) { * @param key * @param count if positive, return an array of distinct elements. * If negative the behavior changes and the command is allowed to - * return the same element multiple times + * return the same element multiple times * @return A list of randomly selected elements */ @Override @@ -8616,6 +8618,12 @@ public ScanResult> hscan(final String key, final Strin return connection.executeCommand(commandObjects.hscan(key, cursor, params)); } + @Override + public ScanResult hscanNoValues(final String key, final String cursor, final ScanParams params) { + checkIsInMultiOrPipeline(); + return connection.executeCommand(commandObjects.hscanNoValues(key, cursor, params)); + } + @Override public ScanResult sscan(final String key, final String cursor, final ScanParams params) { checkIsInMultiOrPipeline(); @@ -8758,7 +8766,7 @@ public long clusterKeySlot(final String key) { public long clusterCountFailureReports(final String nodeId) { checkIsInMultiOrPipeline(); connection.sendCommand(CLUSTER, "COUNT-FAILURE-REPORTS", nodeId); - return connection.getIntegerReply(); + return connection.getIntegerReply(); } @Override @@ -8826,12 +8834,20 @@ public String clusterFailover(ClusterFailoverOption failoverOption) { } @Override + @Deprecated public List clusterSlots() { checkIsInMultiOrPipeline(); connection.sendCommand(CLUSTER, ClusterKeyword.SLOTS); return connection.getObjectMultiBulkReply(); } + @Override + public List clusterShards() { + checkIsInMultiOrPipeline(); + connection.sendCommand(CLUSTER, ClusterKeyword.SHARDS); + return BuilderFactory.CLUSTER_SHARD_INFO_LIST.build(connection.getObjectMultiBulkReply()); + } + @Override public String clusterMyId() { checkIsInMultiOrPipeline(); @@ -9259,6 +9275,12 @@ public String lolwut(LolwutParams lolwutParams) { return connection.getBulkReply(); } + @Override + public String reset() { + connection.sendCommand(Command.RESET); + return connection.getStatusCodeReply(); + } + @Override public String latencyDoctor() { checkIsInMultiOrPipeline(); @@ -9266,6 +9288,26 @@ public String latencyDoctor() { return connection.getBulkReply(); } + public Map latencyLatest() { + checkIsInMultiOrPipeline(); + connection.sendCommand(LATENCY, LATEST); + return BuilderFactory.LATENCY_LATEST_RESPONSE.build(connection.getOne()); + } + + public List latencyHistory(LatencyEvent event) { + checkIsInMultiOrPipeline(); + connection.sendCommand(new CommandArguments(LATENCY).add(HISTORY).add(event)); + return BuilderFactory.LATENCY_HISTORY_RESPONSE.build(connection.getOne()); + } + + public long latencyReset(LatencyEvent... events) { + checkIsInMultiOrPipeline(); + CommandArguments arguments = new CommandArguments(LATENCY).add(Keyword.RESET); + Arrays.stream(events).forEach(arguments::add); + connection.sendCommand(arguments); + return connection.getIntegerReply(); + } + @Override public StreamEntryID xadd(final String key, final StreamEntryID id, final Map hash) { checkIsInMultiOrPipeline(); diff --git a/src/main/java/redis/clients/jedis/JedisClientConfig.java b/src/main/java/redis/clients/jedis/JedisClientConfig.java index beb0eabba6..0ad6e979f6 100644 --- a/src/main/java/redis/clients/jedis/JedisClientConfig.java +++ b/src/main/java/redis/clients/jedis/JedisClientConfig.java @@ -80,4 +80,11 @@ default HostAndPortMapper getHostAndPortMapper() { return null; } + /** + * Modify the behavior of internally executing CLIENT SETINFO command. + * @return CLIENT SETINFO config + */ + default ClientSetInfoConfig getClientSetInfoConfig() { + return ClientSetInfoConfig.DEFAULT; + } } diff --git a/src/main/java/redis/clients/jedis/JedisCluster.java b/src/main/java/redis/clients/jedis/JedisCluster.java index e9bb606191..55495e6513 100644 --- a/src/main/java/redis/clients/jedis/JedisCluster.java +++ b/src/main/java/redis/clients/jedis/JedisCluster.java @@ -12,6 +12,8 @@ public class JedisCluster extends UnifiedJedis { + public static final String INIT_NO_ERROR_PROPERTY = "jedis.cluster.initNoError"; + /** * Default timeout in milliseconds. */ @@ -170,36 +172,56 @@ public JedisCluster(Set clusterNodes, int connectionTimeout, int so maxAttempts, poolConfig); } - public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig, - int maxAttempts, GenericObjectPoolConfig poolConfig) { + public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig) { + this(clusterNodes, clientConfig, DEFAULT_MAX_ATTEMPTS); + } + + public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig, int maxAttempts) { this(clusterNodes, clientConfig, maxAttempts, - Duration.ofMillis((long) clientConfig.getSocketTimeoutMillis() * maxAttempts), poolConfig); + Duration.ofMillis((long) clientConfig.getSocketTimeoutMillis() * maxAttempts)); + } + + public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig, int maxAttempts, + Duration maxTotalRetriesDuration) { + this(new ClusterConnectionProvider(clusterNodes, clientConfig), maxAttempts, maxTotalRetriesDuration, + clientConfig.getRedisProtocol()); } public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig, - int maxAttempts, Duration maxTotalRetriesDuration, GenericObjectPoolConfig poolConfig) { - super(clusterNodes, clientConfig, poolConfig, maxAttempts, maxTotalRetriesDuration); + this(clusterNodes, clientConfig, DEFAULT_MAX_ATTEMPTS, poolConfig); } - public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig) { - this(clusterNodes, clientConfig, DEFAULT_MAX_ATTEMPTS); + public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig, int maxAttempts, + GenericObjectPoolConfig poolConfig) { + this(clusterNodes, clientConfig, maxAttempts, + Duration.ofMillis((long) clientConfig.getSocketTimeoutMillis() * maxAttempts), poolConfig); } - public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig, int maxAttempts) { - super(clusterNodes, clientConfig, maxAttempts); + public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig, + GenericObjectPoolConfig poolConfig, Duration topologyRefreshPeriod, int maxAttempts, + Duration maxTotalRetriesDuration) { + this(new ClusterConnectionProvider(clusterNodes, clientConfig, poolConfig, topologyRefreshPeriod), + maxAttempts, maxTotalRetriesDuration, clientConfig.getRedisProtocol()); } public JedisCluster(Set clusterNodes, JedisClientConfig clientConfig, int maxAttempts, - Duration maxTotalRetriesDuration) { - super(clusterNodes, clientConfig, maxAttempts, maxTotalRetriesDuration); + Duration maxTotalRetriesDuration, GenericObjectPoolConfig poolConfig) { + this(new ClusterConnectionProvider(clusterNodes, clientConfig, poolConfig), maxAttempts, maxTotalRetriesDuration, + clientConfig.getRedisProtocol()); } + // Uses a fetched connection to process protocol. Should be avoided if possible. public JedisCluster(ClusterConnectionProvider provider, int maxAttempts, Duration maxTotalRetriesDuration) { super(provider, maxAttempts, maxTotalRetriesDuration); } + private JedisCluster(ClusterConnectionProvider provider, int maxAttempts, Duration maxTotalRetriesDuration, + RedisProtocol protocol) { + super(provider, maxAttempts, maxTotalRetriesDuration, protocol); + } + public Map getClusterNodes() { return ((ClusterConnectionProvider) provider).getNodes(); } diff --git a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java index a4cc2d1d63..bea4982fd4 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java +++ b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java @@ -1,5 +1,6 @@ package redis.clients.jedis; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -10,17 +11,26 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import redis.clients.jedis.exceptions.JedisClusterOperationException; import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.util.SafeEncoder; +import static redis.clients.jedis.JedisCluster.INIT_NO_ERROR_PROPERTY; + public class JedisClusterInfoCache { + private static final Logger logger = LoggerFactory.getLogger(JedisClusterInfoCache.class); + private final Map nodes = new HashMap<>(); private final ConnectionPool[] slots = new ConnectionPool[Protocol.CLUSTER_HASHSLOTS]; private final HostAndPort[] slotNodes = new HostAndPort[Protocol.CLUSTER_HASHSLOTS]; @@ -36,21 +46,75 @@ public class JedisClusterInfoCache { private static final int MASTER_NODE_INDEX = 2; + /** + * The single thread executor for the topology refresh task. + */ + private ScheduledExecutorService topologyRefreshExecutor = null; + + class TopologyRefreshTask implements Runnable { + @Override + public void run() { + logger.debug("Cluster topology refresh run, old nodes: {}", nodes.keySet()); + renewClusterSlots(null); + logger.debug("Cluster topology refresh run, new nodes: {}", nodes.keySet()); + } + } + public JedisClusterInfoCache(final JedisClientConfig clientConfig, final Set startNodes) { this(clientConfig, null, startNodes); } public JedisClusterInfoCache(final JedisClientConfig clientConfig, final GenericObjectPoolConfig poolConfig, final Set startNodes) { + this(clientConfig, poolConfig, startNodes, null); + } + + public JedisClusterInfoCache(final JedisClientConfig clientConfig, + final GenericObjectPoolConfig poolConfig, final Set startNodes, + final Duration topologyRefreshPeriod) { this.poolConfig = poolConfig; this.clientConfig = clientConfig; this.startNodes = startNodes; + if (topologyRefreshPeriod != null) { + logger.info("Cluster topology refresh start, period: {}, startNodes: {}", topologyRefreshPeriod, startNodes); + topologyRefreshExecutor = Executors.newSingleThreadScheduledExecutor(); + topologyRefreshExecutor.scheduleWithFixedDelay(new TopologyRefreshTask(), topologyRefreshPeriod.toMillis(), + topologyRefreshPeriod.toMillis(), TimeUnit.MILLISECONDS); + } + } + + /** + * Check whether the number and order of slots in the cluster topology are equal to CLUSTER_HASHSLOTS + * @param slotsInfo the cluster topology + * @return if slots is ok, return true, elese return false. + */ + private boolean checkClusterSlotSequence(List slotsInfo) { + List slots = new ArrayList<>(); + for (Object slotInfoObj : slotsInfo) { + List slotInfo = (List)slotInfoObj; + slots.addAll(getAssignedSlotArray(slotInfo)); + } + Collections.sort(slots); + if (slots.size() != Protocol.CLUSTER_HASHSLOTS) { + return false; + } + for (int i = 0; i < Protocol.CLUSTER_HASHSLOTS; ++i) { + if (i != slots.get(i)) { + return false; + } + } + return true; } public void discoverClusterNodesAndSlots(Connection jedis) { List slotsInfo = executeClusterSlots(jedis); - if (slotsInfo.isEmpty()) { - throw new JedisClusterOperationException("Cluster slots list is empty."); + if (System.getProperty(INIT_NO_ERROR_PROPERTY) == null) { + if (slotsInfo.isEmpty()) { + throw new JedisClusterOperationException("Cluster slots list is empty."); + } + if (!checkClusterSlotSequence(slotsInfo)) { + throw new JedisClusterOperationException("Cluster slots have holes."); + } } w.lock(); try { @@ -133,8 +197,13 @@ public void renewClusterSlots(Connection jedis) { private void discoverClusterSlots(Connection jedis) { List slotsInfo = executeClusterSlots(jedis); - if (slotsInfo.isEmpty()) { - throw new JedisClusterOperationException("Cluster slots list is empty."); + if (System.getProperty(INIT_NO_ERROR_PROPERTY) == null) { + if (slotsInfo.isEmpty()) { + throw new JedisClusterOperationException("Cluster slots list is empty."); + } + if (!checkClusterSlotSequence(slotsInfo)) { + throw new JedisClusterOperationException("Cluster slots have holes."); + } } w.lock(); try { @@ -308,6 +377,14 @@ public void reset() { } } + public void close() { + reset(); + if (topologyRefreshExecutor != null) { + logger.info("Cluster topology refresh shutdown, startNodes: {}", startNodes); + topologyRefreshExecutor.shutdownNow(); + } + } + public static String getNodeKey(HostAndPort hnp) { //return hnp.getHost() + ":" + hnp.getPort(); return hnp.toString(); diff --git a/src/main/java/redis/clients/jedis/JedisFactory.java b/src/main/java/redis/clients/jedis/JedisFactory.java index b84e2b05ae..0e07ccc286 100644 --- a/src/main/java/redis/clients/jedis/JedisFactory.java +++ b/src/main/java/redis/clients/jedis/JedisFactory.java @@ -197,7 +197,7 @@ public boolean validateObject(PooledObject pooledJedis) { && jedis.getConnection().isConnected() && jedis.ping().equals("PONG"); } catch (final Exception e) { - logger.error("Error while validating pooled Jedis object.", e); + logger.warn("Error while validating pooled Jedis object.", e); return false; } } diff --git a/src/main/java/redis/clients/jedis/JedisMetaInfo.java b/src/main/java/redis/clients/jedis/JedisMetaInfo.java new file mode 100644 index 0000000000..04470de70a --- /dev/null +++ b/src/main/java/redis/clients/jedis/JedisMetaInfo.java @@ -0,0 +1,42 @@ +package redis.clients.jedis; + +import java.io.InputStream; +import java.util.Properties; +import org.slf4j.LoggerFactory; + +/** + * Jedis Meta info load version groupId + */ +class JedisMetaInfo { + + private static final String groupId; + private static final String artifactId; + private static final String version; + + static { + Properties p = new Properties(); + try (InputStream in = JedisMetaInfo.class.getClassLoader() + .getResourceAsStream("redis/clients/jedis/pom.properties")) { + p.load(in); + } catch (Exception e) { + LoggerFactory.getLogger(JedisMetaInfo.class) + .error("Load Jedis meta info from pom.properties failed", e); + } + + groupId = p.getProperty("groupId", null); + artifactId = p.getProperty("artifactId", null); + version = p.getProperty("version", null); + } + + public static String getGroupId() { + return groupId; + } + + public static String getArtifactId() { + return artifactId; + } + + public static String getVersion() { + return version; + } +} diff --git a/src/main/java/redis/clients/jedis/JedisPooled.java b/src/main/java/redis/clients/jedis/JedisPooled.java index bc751527ca..c6d022e094 100644 --- a/src/main/java/redis/clients/jedis/JedisPooled.java +++ b/src/main/java/redis/clients/jedis/JedisPooled.java @@ -53,7 +53,7 @@ public JedisPooled(final String host, final int port) { } public JedisPooled(final HostAndPort hostAndPort) { - this(new PooledConnectionProvider(hostAndPort)); + super(hostAndPort); } public JedisPooled(final String host, final int port, final boolean ssl) { @@ -73,7 +73,7 @@ public JedisPooled(final String host, final int port, final String user, final S } public JedisPooled(final HostAndPort hostAndPort, final JedisClientConfig clientConfig) { - this(new PooledConnectionProvider(hostAndPort, clientConfig)); + super(hostAndPort, clientConfig); } public JedisPooled(PooledObjectFactory factory) { @@ -373,12 +373,13 @@ public JedisPooled(final GenericObjectPoolConfig poolConfig, final H public JedisPooled(final HostAndPort hostAndPort, final JedisClientConfig clientConfig, final GenericObjectPoolConfig poolConfig) { - this(new PooledConnectionProvider(hostAndPort, clientConfig, poolConfig)); + super(new PooledConnectionProvider(hostAndPort, clientConfig, poolConfig), clientConfig.getRedisProtocol()); } public JedisPooled(final GenericObjectPoolConfig poolConfig, final JedisSocketFactory jedisSocketFactory, final JedisClientConfig clientConfig) { - this(new ConnectionFactory(jedisSocketFactory, clientConfig), poolConfig); + super(new PooledConnectionProvider(new ConnectionFactory(jedisSocketFactory, clientConfig), poolConfig), + clientConfig.getRedisProtocol()); } public JedisPooled(GenericObjectPoolConfig poolConfig, PooledObjectFactory factory) { diff --git a/src/main/java/redis/clients/jedis/JedisPubSubBase.java b/src/main/java/redis/clients/jedis/JedisPubSubBase.java index 7092680e33..552310e4de 100644 --- a/src/main/java/redis/clients/jedis/JedisPubSubBase.java +++ b/src/main/java/redis/clients/jedis/JedisPubSubBase.java @@ -172,7 +172,7 @@ private void process() { } else { throw new JedisException("Unknown message type: " + reply); } - } while (isSubscribed()); + } while (!Thread.currentThread().isInterrupted() && isSubscribed()); // /* Invalidate instance since this thread is no longer listening */ // this.client = null; diff --git a/src/main/java/redis/clients/jedis/JedisSentineled.java b/src/main/java/redis/clients/jedis/JedisSentineled.java index 7a6c0cc5c0..0ea0221c1a 100644 --- a/src/main/java/redis/clients/jedis/JedisSentineled.java +++ b/src/main/java/redis/clients/jedis/JedisSentineled.java @@ -8,13 +8,15 @@ public class JedisSentineled extends UnifiedJedis { public JedisSentineled(String masterName, final JedisClientConfig masterClientConfig, Set sentinels, final JedisClientConfig sentinelClientConfig) { - this(new SentineledConnectionProvider(masterName, masterClientConfig, sentinels, sentinelClientConfig)); + super(new SentineledConnectionProvider(masterName, masterClientConfig, sentinels, sentinelClientConfig), + masterClientConfig.getRedisProtocol()); } public JedisSentineled(String masterName, final JedisClientConfig masterClientConfig, final GenericObjectPoolConfig poolConfig, Set sentinels, final JedisClientConfig sentinelClientConfig) { - this(new SentineledConnectionProvider(masterName, masterClientConfig, poolConfig, sentinels, sentinelClientConfig)); + super(new SentineledConnectionProvider(masterName, masterClientConfig, poolConfig, sentinels, sentinelClientConfig), + masterClientConfig.getRedisProtocol()); } public JedisSentineled(SentineledConnectionProvider sentineledConnectionProvider) { @@ -24,4 +26,9 @@ public JedisSentineled(SentineledConnectionProvider sentineledConnectionProvider public HostAndPort getCurrentMaster() { return ((SentineledConnectionProvider) provider).getCurrentMaster(); } + + @Override + public Pipeline pipelined() { + return (Pipeline) super.pipelined(); + } } diff --git a/src/main/java/redis/clients/jedis/JedisShardedPubSubBase.java b/src/main/java/redis/clients/jedis/JedisShardedPubSubBase.java index f0a251f61f..2b2ce944fe 100644 --- a/src/main/java/redis/clients/jedis/JedisShardedPubSubBase.java +++ b/src/main/java/redis/clients/jedis/JedisShardedPubSubBase.java @@ -99,7 +99,7 @@ private void process() { } else { throw new JedisException("Unknown message type: " + reply); } - } while (isSubscribed()); + } while (!Thread.currentThread().isInterrupted() && isSubscribed()); // /* Invalidate instance since this thread is no longer listening */ // this.client = null; diff --git a/src/main/java/redis/clients/jedis/MultiClusterClientConfig.java b/src/main/java/redis/clients/jedis/MultiClusterClientConfig.java index c39efae7d4..15956ebed4 100644 --- a/src/main/java/redis/clients/jedis/MultiClusterClientConfig.java +++ b/src/main/java/redis/clients/jedis/MultiClusterClientConfig.java @@ -1,13 +1,15 @@ package redis.clients.jedis; +import io.github.resilience4j.circuitbreaker.CallNotPermittedException; import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.SlidingWindowType; -import redis.clients.jedis.exceptions.JedisConnectionException; -import redis.clients.jedis.exceptions.JedisValidationException; import java.time.Duration; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import redis.clients.jedis.exceptions.JedisConnectionException; +import redis.clients.jedis.exceptions.JedisValidationException; + /** * @author Allen Terleto (aterleto) @@ -22,12 +24,13 @@ * not passed through to Jedis users. *

*/ +// TODO: move public final class MultiClusterClientConfig { private static final int RETRY_MAX_ATTEMPTS_DEFAULT = 3; private static final int RETRY_WAIT_DURATION_DEFAULT = 500; // measured in milliseconds private static final int RETRY_WAIT_DURATION_EXPONENTIAL_BACKOFF_MULTIPLIER_DEFAULT = 2; - private static final Class RETRY_INCLUDED_EXCEPTIONS_DEFAULT = JedisConnectionException.class; + private static final List RETRY_INCLUDED_EXCEPTIONS_DEFAULT = Arrays.asList(JedisConnectionException.class); private static final float CIRCUIT_BREAKER_FAILURE_RATE_THRESHOLD_DEFAULT = 50.0f; // measured as percentage private static final int CIRCUIT_BREAKER_SLIDING_WINDOW_MIN_CALLS_DEFAULT = 100; @@ -35,7 +38,9 @@ public final class MultiClusterClientConfig { private static final int CIRCUIT_BREAKER_SLIDING_WINDOW_SIZE_DEFAULT = 100; private static final int CIRCUIT_BREAKER_SLOW_CALL_DURATION_THRESHOLD_DEFAULT = 60000; // measured in milliseconds private static final float CIRCUIT_BREAKER_SLOW_CALL_RATE_THRESHOLD_DEFAULT = 100.0f; // measured as percentage - private static final Class CIRCUIT_BREAKER_INCLUDED_EXCEPTIONS_DEFAULT = JedisConnectionException.class; + private static final List CIRCUIT_BREAKER_INCLUDED_EXCEPTIONS_DEFAULT = Arrays.asList(JedisConnectionException.class); + + private static final List> FALLBACK_EXCEPTIONS_DEFAULT = Arrays.asList(CallNotPermittedException.class); private final ClusterConfig[] clusterConfigs; @@ -99,6 +104,7 @@ public final class MultiClusterClientConfig { * failure nor success, even if the exceptions is part of recordExceptions */ private List circuitBreakerIgnoreExceptionList; + private List> fallbackExceptionList; public MultiClusterClientConfig(ClusterConfig[] clusterConfigs) { this.clusterConfigs = clusterConfigs; @@ -160,6 +166,10 @@ public SlidingWindowType getCircuitBreakerSlidingWindowType() { return circuitBreakerSlidingWindowType; } + public List> getFallbackExceptionList() { + return fallbackExceptionList; + } + public static class ClusterConfig { private int priority; @@ -195,8 +205,8 @@ public static class Builder { private int retryMaxAttempts = RETRY_MAX_ATTEMPTS_DEFAULT; private int retryWaitDuration = RETRY_WAIT_DURATION_DEFAULT; private int retryWaitDurationExponentialBackoffMultiplier = RETRY_WAIT_DURATION_EXPONENTIAL_BACKOFF_MULTIPLIER_DEFAULT; - private List retryIncludedExceptionList; - private List retryIgnoreExceptionList; + private List retryIncludedExceptionList = RETRY_INCLUDED_EXCEPTIONS_DEFAULT; + private List retryIgnoreExceptionList = null; private float circuitBreakerFailureRateThreshold = CIRCUIT_BREAKER_FAILURE_RATE_THRESHOLD_DEFAULT; private int circuitBreakerSlidingWindowMinCalls = CIRCUIT_BREAKER_SLIDING_WINDOW_MIN_CALLS_DEFAULT; @@ -204,9 +214,9 @@ public static class Builder { private int circuitBreakerSlidingWindowSize = CIRCUIT_BREAKER_SLIDING_WINDOW_SIZE_DEFAULT; private int circuitBreakerSlowCallDurationThreshold = CIRCUIT_BREAKER_SLOW_CALL_DURATION_THRESHOLD_DEFAULT; private float circuitBreakerSlowCallRateThreshold = CIRCUIT_BREAKER_SLOW_CALL_RATE_THRESHOLD_DEFAULT; - private List circuitBreakerIncludedExceptionList; - private List circuitBreakerIgnoreExceptionList; - private List> circuitBreakerFallbackExceptionList; + private List circuitBreakerIncludedExceptionList = CIRCUIT_BREAKER_INCLUDED_EXCEPTIONS_DEFAULT; + private List circuitBreakerIgnoreExceptionList = null; + private List> fallbackExceptionList = FALLBACK_EXCEPTIONS_DEFAULT; public Builder(ClusterConfig[] clusterConfigs) { @@ -219,6 +229,10 @@ public Builder(ClusterConfig[] clusterConfigs) { this.clusterConfigs = clusterConfigs; } + public Builder(List clusterConfigs) { + this(clusterConfigs.toArray(new ClusterConfig[0])); + } + public Builder retryMaxAttempts(int retryMaxAttempts) { this.retryMaxAttempts = retryMaxAttempts; return this; @@ -284,8 +298,16 @@ public Builder circuitBreakerIgnoreExceptionList(List circuitBreakerIgnor return this; } + /** + * @deprecated Use {@link #fallbackExceptionList(java.util.List)}. + */ + @Deprecated public Builder circuitBreakerFallbackExceptionList(List> circuitBreakerFallbackExceptionList) { - this.circuitBreakerFallbackExceptionList = circuitBreakerFallbackExceptionList; + return fallbackExceptionList(circuitBreakerFallbackExceptionList); + } + + public Builder fallbackExceptionList(List> fallbackExceptionList) { + this.fallbackExceptionList = fallbackExceptionList; return this; } @@ -296,16 +318,9 @@ public MultiClusterClientConfig build() { config.retryWaitDuration = Duration.ofMillis(this.retryWaitDuration); config.retryWaitDurationExponentialBackoffMultiplier = this.retryWaitDurationExponentialBackoffMultiplier; - if (this.retryIncludedExceptionList != null && !retryIncludedExceptionList.isEmpty()) - config.retryIncludedExceptionList = this.retryIncludedExceptionList; - - else { - config.retryIncludedExceptionList = new ArrayList<>(); - config.retryIncludedExceptionList.add(RETRY_INCLUDED_EXCEPTIONS_DEFAULT); - } + config.retryIncludedExceptionList = this.retryIncludedExceptionList; - if (this.retryIgnoreExceptionList != null && !retryIgnoreExceptionList.isEmpty()) - config.retryIgnoreExceptionList = this.retryIgnoreExceptionList; + config.retryIgnoreExceptionList = this.retryIgnoreExceptionList; config.circuitBreakerFailureRateThreshold = this.circuitBreakerFailureRateThreshold; config.circuitBreakerSlidingWindowMinCalls = this.circuitBreakerSlidingWindowMinCalls; @@ -314,16 +329,11 @@ public MultiClusterClientConfig build() { config.circuitBreakerSlowCallDurationThreshold = Duration.ofMillis(this.circuitBreakerSlowCallDurationThreshold); config.circuitBreakerSlowCallRateThreshold = this.circuitBreakerSlowCallRateThreshold; - if (this.circuitBreakerIncludedExceptionList != null && !circuitBreakerIncludedExceptionList.isEmpty()) - config.circuitBreakerIncludedExceptionList = this.circuitBreakerIncludedExceptionList; + config.circuitBreakerIncludedExceptionList = this.circuitBreakerIncludedExceptionList; - else { - config.circuitBreakerIncludedExceptionList = new ArrayList<>(); - config.circuitBreakerIncludedExceptionList.add(CIRCUIT_BREAKER_INCLUDED_EXCEPTIONS_DEFAULT); - } + config.circuitBreakerIgnoreExceptionList = this.circuitBreakerIgnoreExceptionList; - if (this.circuitBreakerIgnoreExceptionList != null && !circuitBreakerIgnoreExceptionList.isEmpty()) - config.circuitBreakerIgnoreExceptionList = this.circuitBreakerIgnoreExceptionList; + config.fallbackExceptionList = this.fallbackExceptionList; return config; } diff --git a/src/main/java/redis/clients/jedis/MultiNodePipelineBase.java b/src/main/java/redis/clients/jedis/MultiNodePipelineBase.java index eef6b2a810..13f2730ab4 100644 --- a/src/main/java/redis/clients/jedis/MultiNodePipelineBase.java +++ b/src/main/java/redis/clients/jedis/MultiNodePipelineBase.java @@ -1,6 +1,5 @@ package redis.clients.jedis; -import java.io.Closeable; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; @@ -14,16 +13,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import redis.clients.jedis.commands.PipelineBinaryCommands; -import redis.clients.jedis.commands.PipelineCommands; -import redis.clients.jedis.commands.RedisModulePipelineCommands; import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.graph.GraphCommandObjects; import redis.clients.jedis.providers.ConnectionProvider; import redis.clients.jedis.util.IOUtils; -public abstract class MultiNodePipelineBase extends PipelineBase - implements PipelineCommands, PipelineBinaryCommands, RedisModulePipelineCommands, Closeable { +public abstract class MultiNodePipelineBase extends PipelineBase { private final Logger log = LoggerFactory.getLogger(getClass()); @@ -68,9 +63,6 @@ protected final Response appendCommand(CommandObject commandObject) { queue = pipelinedResponses.get(nodeKey); connection = connections.get(nodeKey); } else { - pipelinedResponses.putIfAbsent(nodeKey, new LinkedList<>()); - queue = pipelinedResponses.get(nodeKey); - Connection newOne = getConnection(nodeKey); connections.putIfAbsent(nodeKey, newOne); connection = connections.get(nodeKey); @@ -78,6 +70,9 @@ protected final Response appendCommand(CommandObject commandObject) { log.debug("Duplicate connection to {}, closing it.", nodeKey); IOUtils.closeQuietly(newOne); } + + pipelinedResponses.putIfAbsent(nodeKey, new LinkedList<>()); + queue = pipelinedResponses.get(nodeKey); } connection.sendCommand(commandObject.getArguments()); diff --git a/src/main/java/redis/clients/jedis/Pipeline.java b/src/main/java/redis/clients/jedis/Pipeline.java index 67e3523702..36fab65602 100644 --- a/src/main/java/redis/clients/jedis/Pipeline.java +++ b/src/main/java/redis/clients/jedis/Pipeline.java @@ -7,16 +7,12 @@ import java.util.Queue; import redis.clients.jedis.commands.DatabasePipelineCommands; -import redis.clients.jedis.commands.PipelineBinaryCommands; -import redis.clients.jedis.commands.PipelineCommands; -import redis.clients.jedis.commands.RedisModulePipelineCommands; import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.graph.GraphCommandObjects; import redis.clients.jedis.params.*; import redis.clients.jedis.util.KeyValue; -public class Pipeline extends PipelineBase implements PipelineCommands, PipelineBinaryCommands, - DatabasePipelineCommands, RedisModulePipelineCommands, Closeable { +public class Pipeline extends PipelineBase implements DatabasePipelineCommands, Closeable { private final Queue> pipelinedResponses = new LinkedList<>(); protected final Connection connection; @@ -66,8 +62,8 @@ public void close() { public void sync() { if (!hasPipelinedResponse()) return; List unformatted = connection.getMany(pipelinedResponses.size()); - for (Object o : unformatted) { - pipelinedResponses.poll().set(o); + for (Object rawReply : unformatted) { + pipelinedResponses.poll().set(rawReply); } } @@ -81,10 +77,10 @@ public List syncAndReturnAll() { if (hasPipelinedResponse()) { List unformatted = connection.getMany(pipelinedResponses.size()); List formatted = new ArrayList<>(); - for (Object o : unformatted) { + for (Object rawReply : unformatted) { try { Response response = pipelinedResponses.poll(); - response.set(o); + response.set(rawReply); formatted.add(response.get()); } catch (JedisDataException e) { formatted.add(e); diff --git a/src/main/java/redis/clients/jedis/PipelineBase.java b/src/main/java/redis/clients/jedis/PipelineBase.java index 4c95e187d4..2f4d246929 100644 --- a/src/main/java/redis/clients/jedis/PipelineBase.java +++ b/src/main/java/redis/clients/jedis/PipelineBase.java @@ -1,4233 +1,12 @@ package redis.clients.jedis; -import java.io.Closeable; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.json.JSONArray; - -import redis.clients.jedis.args.*; -import redis.clients.jedis.bloom.*; -import redis.clients.jedis.commands.PipelineBinaryCommands; -import redis.clients.jedis.commands.PipelineCommands; -import redis.clients.jedis.commands.ProtocolCommand; -import redis.clients.jedis.commands.RedisModulePipelineCommands; -import redis.clients.jedis.graph.GraphCommandObjects; -import redis.clients.jedis.graph.ResultSet; -import redis.clients.jedis.json.JsonSetParams; -import redis.clients.jedis.json.Path; -import redis.clients.jedis.json.Path2; -import redis.clients.jedis.json.JsonObjectMapper; -import redis.clients.jedis.params.*; -import redis.clients.jedis.resps.*; -import redis.clients.jedis.search.*; -import redis.clients.jedis.search.aggr.AggregationBuilder; -import redis.clients.jedis.search.aggr.AggregationResult; -import redis.clients.jedis.search.schemafields.SchemaField; -import redis.clients.jedis.timeseries.*; -import redis.clients.jedis.util.KeyValue; - -public abstract class PipelineBase implements PipelineCommands, PipelineBinaryCommands, - RedisModulePipelineCommands, Closeable { - - protected final CommandObjects commandObjects; - private GraphCommandObjects graphCommandObjects; - - public PipelineBase(CommandObjects commandObjects) { - this.commandObjects = commandObjects; - } - - /** - * Sub-classes must call this method, if graph commands are going to be used. - */ - protected final void setGraphCommands(GraphCommandObjects graphCommandObjects) { - this.graphCommandObjects = graphCommandObjects; - } - - protected abstract Response appendCommand(CommandObject commandObject); - - @Override - public abstract void close(); - - /** - * Synchronize pipeline by reading all responses. - */ - public abstract void sync(); - - @Override - public Response exists(String key) { - return appendCommand(commandObjects.exists(key)); - } - - @Override - public Response exists(String... keys) { - return appendCommand(commandObjects.exists(keys)); - } - - @Override - public Response persist(String key) { - return appendCommand(commandObjects.persist(key)); - } - - @Override - public Response type(String key) { - return appendCommand(commandObjects.type(key)); - } - - @Override - public Response dump(String key) { - return appendCommand(commandObjects.dump(key)); - } - - @Override - public Response restore(String key, long ttl, byte[] serializedValue) { - return appendCommand(commandObjects.restore(key, ttl, serializedValue)); - } - - @Override - public Response restore(String key, long ttl, byte[] serializedValue, RestoreParams params) { - return appendCommand(commandObjects.restore(key, ttl, serializedValue, params)); - } - - @Override - public Response expire(String key, long seconds) { - return appendCommand(commandObjects.expire(key, seconds)); - } - - @Override - public Response expire(String key, long seconds, ExpiryOption expiryOption) { - return appendCommand(commandObjects.expire(key, seconds, expiryOption)); - } - - @Override - public Response pexpire(String key, long milliseconds) { - return appendCommand(commandObjects.pexpire(key, milliseconds)); - } - - @Override - public Response pexpire(String key, long milliseconds, ExpiryOption expiryOption) { - return appendCommand(commandObjects.pexpire(key, milliseconds, expiryOption)); - } - - @Override - public Response expireTime(String key) { - return appendCommand(commandObjects.expireTime(key)); - } - - @Override - public Response pexpireTime(String key) { - return appendCommand(commandObjects.pexpireTime(key)); - } - - @Override - public Response expireAt(String key, long unixTime) { - return appendCommand(commandObjects.expireAt(key, unixTime)); - } - - @Override - public Response expireAt(String key, long unixTime, ExpiryOption expiryOption) { - return appendCommand(commandObjects.expireAt(key, unixTime, expiryOption)); - } - - @Override - public Response pexpireAt(String key, long millisecondsTimestamp) { - return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp)); - } - - @Override - public Response pexpireAt(String key, long millisecondsTimestamp, ExpiryOption expiryOption) { - return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp, expiryOption)); - } - - @Override - public Response ttl(String key) { - return appendCommand(commandObjects.ttl(key)); - } - - @Override - public Response pttl(String key) { - return appendCommand(commandObjects.pttl(key)); - } - - @Override - public Response touch(String key) { - return appendCommand(commandObjects.touch(key)); - } - - @Override - public Response touch(String... keys) { - return appendCommand(commandObjects.touch(keys)); - } - - @Override - public Response> sort(String key) { - return appendCommand(commandObjects.sort(key)); - } - - @Override - public Response sort(String key, String dstKey) { - return appendCommand(commandObjects.sort(key, dstKey)); - } - - @Override - public Response> sort(String key, SortingParams sortingParams) { - return appendCommand(commandObjects.sort(key, sortingParams)); - } - - @Override - public Response sort(String key, SortingParams sortingParams, String dstKey) { - return appendCommand(commandObjects.sort(key, sortingParams, dstKey)); - } - - @Override - public Response> sortReadonly(String key, SortingParams sortingParams) { - return appendCommand(commandObjects.sortReadonly(key, sortingParams)); - } - - @Override - public Response del(String key) { - return appendCommand(commandObjects.del(key)); - } - - @Override - public Response del(String... keys) { - return appendCommand(commandObjects.del(keys)); - } - - @Override - public Response unlink(String key) { - return appendCommand(commandObjects.unlink(key)); - } - - @Override - public Response unlink(String... keys) { - return appendCommand(commandObjects.unlink(keys)); - } - - @Override - public Response copy(String srcKey, String dstKey, boolean replace) { - return appendCommand(commandObjects.copy(srcKey, dstKey, replace)); - } - - @Override - public Response rename(String oldkey, String newkey) { - return appendCommand(commandObjects.rename(oldkey, newkey)); - } - - @Override - public Response renamenx(String oldkey, String newkey) { - return appendCommand(commandObjects.renamenx(oldkey, newkey)); - } - - @Override - public Response memoryUsage(String key) { - return appendCommand(commandObjects.memoryUsage(key)); - } - - @Override - public Response memoryUsage(String key, int samples) { - return appendCommand(commandObjects.memoryUsage(key, samples)); - } - - @Override - public Response objectRefcount(String key) { - return appendCommand(commandObjects.objectRefcount(key)); - } - - @Override - public Response objectEncoding(String key) { - return appendCommand(commandObjects.objectEncoding(key)); - } - - @Override - public Response objectIdletime(String key) { - return appendCommand(commandObjects.objectIdletime(key)); - } - - @Override - public Response objectFreq(String key) { - return appendCommand(commandObjects.objectFreq(key)); - } - - @Override - public Response migrate(String host, int port, String key, int timeout) { - return appendCommand(commandObjects.migrate(host, port, key, timeout)); - } - - @Override - public Response migrate(String host, int port, int timeout, MigrateParams params, String... keys) { - return appendCommand(commandObjects.migrate(host, port, timeout, params, keys)); - } - - @Override - public Response> keys(String pattern) { - return appendCommand(commandObjects.keys(pattern)); - } - - @Override - public Response> scan(String cursor) { - return appendCommand(commandObjects.scan(cursor)); - } - - @Override - public Response> scan(String cursor, ScanParams params) { - return appendCommand(commandObjects.scan(cursor, params)); - } - - @Override - public Response> scan(String cursor, ScanParams params, String type) { - return appendCommand(commandObjects.scan(cursor, params, type)); - } - - @Override - public Response randomKey() { - return appendCommand(commandObjects.randomKey()); - } - - @Override - public Response get(String key) { - return appendCommand(commandObjects.get(key)); - } - - @Override - public Response setGet(String key, String value, SetParams params) { - return appendCommand(commandObjects.setGet(key, value, params)); - } - - @Override - public Response getDel(String key) { - return appendCommand(commandObjects.getDel(key)); - } - - @Override - public Response getEx(String key, GetExParams params) { - return appendCommand(commandObjects.getEx(key, params)); - } - - @Override - public Response setbit(String key, long offset, boolean value) { - return appendCommand(commandObjects.setbit(key, offset, value)); - } - - @Override - public Response getbit(String key, long offset) { - return appendCommand(commandObjects.getbit(key, offset)); - } - - @Override - public Response setrange(String key, long offset, String value) { - return appendCommand(commandObjects.setrange(key, offset, value)); - } - - @Override - public Response getrange(String key, long startOffset, long endOffset) { - return appendCommand(commandObjects.getrange(key, startOffset, endOffset)); - } - - @Override - public Response getSet(String key, String value) { - return appendCommand(commandObjects.getSet(key, value)); - } - - @Override - public Response setnx(String key, String value) { - return appendCommand(commandObjects.setnx(key, value)); - } - - @Override - public Response setex(String key, long seconds, String value) { - return appendCommand(commandObjects.setex(key, seconds, value)); - } - - @Override - public Response psetex(String key, long milliseconds, String value) { - return appendCommand(commandObjects.psetex(key, milliseconds, value)); - } - - @Override - public Response> mget(String... keys) { - return appendCommand(commandObjects.mget(keys)); - } - - @Override - public Response mset(String... keysvalues) { - return appendCommand(commandObjects.mset(keysvalues)); - } - - @Override - public Response msetnx(String... keysvalues) { - return appendCommand(commandObjects.msetnx(keysvalues)); - } - - @Override - public Response incr(String key) { - return appendCommand(commandObjects.incr(key)); - } - - @Override - public Response incrBy(String key, long increment) { - return appendCommand(commandObjects.incrBy(key, increment)); - } - - @Override - public Response incrByFloat(String key, double increment) { - return appendCommand(commandObjects.incrByFloat(key, increment)); - } - - @Override - public Response decr(String key) { - return appendCommand(commandObjects.decr(key)); - } - - @Override - public Response decrBy(String key, long decrement) { - return appendCommand(commandObjects.decrBy(key, decrement)); - } - - @Override - public Response append(String key, String value) { - return appendCommand(commandObjects.append(key, value)); - } - - @Override - public Response substr(String key, int start, int end) { - return appendCommand(commandObjects.substr(key, start, end)); - } - - @Override - public Response strlen(String key) { - return appendCommand(commandObjects.strlen(key)); - } - - @Override - public Response bitcount(String key) { - return appendCommand(commandObjects.bitcount(key)); - } - - @Override - public Response bitcount(String key, long start, long end) { - return appendCommand(commandObjects.bitcount(key, start, end)); - } - - @Override - public Response bitcount(String key, long start, long end, BitCountOption option) { - return appendCommand(commandObjects.bitcount(key, start, end, option)); - } - - @Override - public Response bitpos(String key, boolean value) { - return appendCommand(commandObjects.bitpos(key, value)); - } - - @Override - public Response bitpos(String key, boolean value, BitPosParams params) { - return appendCommand(commandObjects.bitpos(key, value, params)); - } - - @Override - public Response> bitfield(String key, String... arguments) { - return appendCommand(commandObjects.bitfield(key, arguments)); - } - - @Override - public Response> bitfieldReadonly(String key, String... arguments) { - return appendCommand(commandObjects.bitfieldReadonly(key, arguments)); - } - - @Override - public Response bitop(BitOP op, String destKey, String... srcKeys) { - return appendCommand(commandObjects.bitop(op, destKey, srcKeys)); - } - - @Override - public Response lcs(String keyA, String keyB, LCSParams params) { - return appendCommand(commandObjects.lcs(keyA, keyB, params)); - } - - @Override - public Response set(String key, String value) { - return appendCommand(commandObjects.set(key, value)); - } - - @Override - public Response set(String key, String value, SetParams params) { - return appendCommand(commandObjects.set(key, value, params)); - } - - @Override - public Response rpush(String key, String... string) { - return appendCommand(commandObjects.rpush(key, string)); - - } - - @Override - public Response lpush(String key, String... string) { - return appendCommand(commandObjects.lpush(key, string)); - } - - @Override - public Response llen(String key) { - return appendCommand(commandObjects.llen(key)); - } - - @Override - public Response> lrange(String key, long start, long stop) { - return appendCommand(commandObjects.lrange(key, start, stop)); - } - - @Override - public Response ltrim(String key, long start, long stop) { - return appendCommand(commandObjects.ltrim(key, start, stop)); - } - - @Override - public Response lindex(String key, long index) { - return appendCommand(commandObjects.lindex(key, index)); - } - - @Override - public Response lset(String key, long index, String value) { - return appendCommand(commandObjects.lset(key, index, value)); - } - - @Override - public Response lrem(String key, long count, String value) { - return appendCommand(commandObjects.lrem(key, count, value)); - } - - @Override - public Response lpop(String key) { - return appendCommand(commandObjects.lpop(key)); - } - - @Override - public Response> lpop(String key, int count) { - return appendCommand(commandObjects.lpop(key, count)); - } - - @Override - public Response lpos(String key, String element) { - return appendCommand(commandObjects.lpos(key, element)); - } - - @Override - public Response lpos(String key, String element, LPosParams params) { - return appendCommand(commandObjects.lpos(key, element, params)); - } - - @Override - public Response> lpos(String key, String element, LPosParams params, long count) { - return appendCommand(commandObjects.lpos(key, element, params, count)); - } - - @Override - public Response rpop(String key) { - return appendCommand(commandObjects.rpop(key)); - } - - @Override - public Response> rpop(String key, int count) { - return appendCommand(commandObjects.rpop(key, count)); - } - - @Override - public Response linsert(String key, ListPosition where, String pivot, String value) { - return appendCommand(commandObjects.linsert(key, where, pivot, value)); - } - - @Override - public Response lpushx(String key, String... strings) { - return appendCommand(commandObjects.lpushx(key, strings)); - } - - @Override - public Response rpushx(String key, String... strings) { - return appendCommand(commandObjects.rpushx(key, strings)); - } - - @Override - public Response> blpop(int timeout, String key) { - return appendCommand(commandObjects.blpop(timeout, key)); - } - - @Override - public Response> blpop(double timeout, String key) { - return appendCommand(commandObjects.blpop(timeout, key)); - } - - @Override - public Response> brpop(int timeout, String key) { - return appendCommand(commandObjects.brpop(timeout, key)); - } - - @Override - public Response> brpop(double timeout, String key) { - return appendCommand(commandObjects.brpop(timeout, key)); - } - - @Override - public Response> blpop(int timeout, String... keys) { - return appendCommand(commandObjects.blpop(timeout, keys)); - } - - @Override - public Response> blpop(double timeout, String... keys) { - return appendCommand(commandObjects.blpop(timeout, keys)); - } - - @Override - public Response> brpop(int timeout, String... keys) { - return appendCommand(commandObjects.brpop(timeout, keys)); - } - - @Override - public Response> brpop(double timeout, String... keys) { - return appendCommand(commandObjects.brpop(timeout, keys)); - } - - @Override - public Response rpoplpush(String srcKey, String dstKey) { - return appendCommand(commandObjects.rpoplpush(srcKey, dstKey)); - } - - @Override - public Response brpoplpush(String source, String destination, int timeout) { - return appendCommand(commandObjects.brpoplpush(source, destination, timeout)); - } - - @Override - public Response lmove(String srcKey, String dstKey, ListDirection from, ListDirection to) { - return appendCommand(commandObjects.lmove(srcKey, dstKey, from, to)); - } - - @Override - public Response blmove(String srcKey, String dstKey, ListDirection from, ListDirection to, double timeout) { - return appendCommand(commandObjects.blmove(srcKey, dstKey, from, to, timeout)); - } - - @Override - public Response>> lmpop(ListDirection direction, String... keys) { - return appendCommand(commandObjects.lmpop(direction, keys)); - } - - @Override - public Response>> lmpop(ListDirection direction, int count, String... keys) { - return appendCommand(commandObjects.lmpop(direction, count, keys)); - } - - @Override - public Response>> blmpop(double timeout, ListDirection direction, String... keys) { - return appendCommand(commandObjects.blmpop(timeout, direction, keys)); - } - - @Override - public Response>> blmpop(double timeout, ListDirection direction, int count, String... keys) { - return appendCommand(commandObjects.blmpop(timeout, direction, count, keys)); - } - - @Override - public Response hset(String key, String field, String value) { - return appendCommand(commandObjects.hset(key, field, value)); - } - - @Override - public Response hset(String key, Map hash) { - return appendCommand(commandObjects.hset(key, hash)); - } - - @Override - public Response hget(String key, String field) { - return appendCommand(commandObjects.hget(key, field)); - } - - @Override - public Response hsetnx(String key, String field, String value) { - return appendCommand(commandObjects.hsetnx(key, field, value)); - } - - @Override - public Response hmset(String key, Map hash) { - return appendCommand(commandObjects.hmset(key, hash)); - } - - @Override - public Response> hmget(String key, String... fields) { - return appendCommand(commandObjects.hmget(key, fields)); - } - - @Override - public Response hincrBy(String key, String field, long value) { - return appendCommand(commandObjects.hincrBy(key, field, value)); - } - - @Override - public Response hincrByFloat(String key, String field, double value) { - return appendCommand(commandObjects.hincrByFloat(key, field, value)); - } - - @Override - public Response hexists(String key, String field) { - return appendCommand(commandObjects.hexists(key, field)); - } - - @Override - public Response hdel(String key, String... field) { - return appendCommand(commandObjects.hdel(key, field)); - } - - @Override - public Response hlen(String key) { - return appendCommand(commandObjects.hlen(key)); - } - - @Override - public Response> hkeys(String key) { - return appendCommand(commandObjects.hkeys(key)); - } - - @Override - public Response> hvals(String key) { - return appendCommand(commandObjects.hvals(key)); - } - - @Override - public Response> hgetAll(String key) { - return appendCommand(commandObjects.hgetAll(key)); - } - - @Override - public Response hrandfield(String key) { - return appendCommand(commandObjects.hrandfield(key)); - } - - @Override - public Response> hrandfield(String key, long count) { - return appendCommand(commandObjects.hrandfield(key, count)); - } - - @Override - public Response>> hrandfieldWithValues(String key, long count) { - return appendCommand(commandObjects.hrandfieldWithValues(key, count)); - } - - @Override - public Response>> hscan(String key, String cursor, ScanParams params) { - return appendCommand(commandObjects.hscan(key, cursor, params)); - } - - @Override - public Response hstrlen(String key, String field) { - return appendCommand(commandObjects.hstrlen(key, field)); - } - - @Override - public Response sadd(String key, String... members) { - return appendCommand(commandObjects.sadd(key, members)); - } - - @Override - public Response> smembers(String key) { - return appendCommand(commandObjects.smembers(key)); - } - - @Override - public Response srem(String key, String... members) { - return appendCommand(commandObjects.srem(key, members)); - } - - @Override - public Response spop(String key) { - return appendCommand(commandObjects.spop(key)); - } - - @Override - public Response> spop(String key, long count) { - return appendCommand(commandObjects.spop(key, count)); - } - - @Override - public Response scard(String key) { - return appendCommand(commandObjects.scard(key)); - } - - @Override - public Response sismember(String key, String member) { - return appendCommand(commandObjects.sismember(key, member)); - } - - @Override - public Response> smismember(String key, String... members) { - return appendCommand(commandObjects.smismember(key, members)); - } - - @Override - public Response srandmember(String key) { - return appendCommand(commandObjects.srandmember(key)); - } - - @Override - public Response> srandmember(String key, int count) { - return appendCommand(commandObjects.srandmember(key, count)); - } - - @Override - public Response> sscan(String key, String cursor, ScanParams params) { - return appendCommand(commandObjects.sscan(key, cursor, params)); - } - - @Override - public Response> sdiff(String... keys) { - return appendCommand(commandObjects.sdiff(keys)); - } - - @Override - public Response sdiffStore(String dstKey, String... keys) { - return appendCommand(commandObjects.sdiffstore(dstKey, keys)); - } - - @Override - public Response> sinter(String... keys) { - return appendCommand(commandObjects.sinter(keys)); - } - - @Override - public Response sinterstore(String dstKey, String... keys) { - return appendCommand(commandObjects.sinterstore(dstKey, keys)); - } - - @Override - public Response sintercard(String... keys) { - return appendCommand(commandObjects.sintercard(keys)); - } - - @Override - public Response sintercard(int limit, String... keys) { - return appendCommand(commandObjects.sintercard(limit, keys)); - } - - @Override - public Response> sunion(String... keys) { - return appendCommand(commandObjects.sunion(keys)); - } - - @Override - public Response sunionstore(String dstKey, String... keys) { - return appendCommand(commandObjects.sunionstore(dstKey, keys)); - } - - @Override - public Response smove(String srcKey, String dstKey, String member) { - return appendCommand(commandObjects.smove(srcKey, dstKey, member)); - } - - @Override - public Response zadd(String key, double score, String member) { - return appendCommand(commandObjects.zadd(key, score, member)); - } - - @Override - public Response zadd(String key, double score, String member, ZAddParams params) { - return appendCommand(commandObjects.zadd(key, score, member, params)); - } - - @Override - public Response zadd(String key, Map scoreMembers) { - return appendCommand(commandObjects.zadd(key, scoreMembers)); - } - - @Override - public Response zadd(String key, Map scoreMembers, ZAddParams params) { - return appendCommand(commandObjects.zadd(key, scoreMembers, params)); - } - - @Override - public Response zaddIncr(String key, double score, String member, ZAddParams params) { - return appendCommand(commandObjects.zaddIncr(key, score, member, params)); - } - - @Override - public Response zrem(String key, String... members) { - return appendCommand(commandObjects.zrem(key, members)); - } - - @Override - public Response zincrby(String key, double increment, String member) { - return appendCommand(commandObjects.zincrby(key, increment, member)); - } - - @Override - public Response zincrby(String key, double increment, String member, ZIncrByParams params) { - return appendCommand(commandObjects.zincrby(key, increment, member, params)); - } - - @Override - public Response zrank(String key, String member) { - return appendCommand(commandObjects.zrank(key, member)); - } - - @Override - public Response zrevrank(String key, String member) { - return appendCommand(commandObjects.zrevrank(key, member)); - } - - @Override - public Response> zrankWithScore(String key, String member) { - return appendCommand(commandObjects.zrankWithScore(key, member)); - } - - @Override - public Response> zrevrankWithScore(String key, String member) { - return appendCommand(commandObjects.zrevrankWithScore(key, member)); - } - - @Override - public Response> zrange(String key, long start, long stop) { - return appendCommand(commandObjects.zrange(key, start, stop)); - } - - @Override - public Response> zrevrange(String key, long start, long stop) { - return appendCommand(commandObjects.zrevrange(key, start, stop)); - } - - @Override - public Response> zrangeWithScores(String key, long start, long stop) { - return appendCommand(commandObjects.zrangeWithScores(key, start, stop)); - } - - @Override - public Response> zrevrangeWithScores(String key, long start, long stop) { - return appendCommand(commandObjects.zrevrangeWithScores(key, start, stop)); - } - - @Override - public Response zrandmember(String key) { - return appendCommand(commandObjects.zrandmember(key)); - } - - @Override - public Response> zrandmember(String key, long count) { - return appendCommand(commandObjects.zrandmember(key, count)); - } - - @Override - public Response> zrandmemberWithScores(String key, long count) { - return appendCommand(commandObjects.zrandmemberWithScores(key, count)); - } - - @Override - public Response zcard(String key) { - return appendCommand(commandObjects.zcard(key)); - } - - @Override - public Response zscore(String key, String member) { - return appendCommand(commandObjects.zscore(key, member)); - } - - @Override - public Response> zmscore(String key, String... members) { - return appendCommand(commandObjects.zmscore(key, members)); - } - - @Override - public Response zpopmax(String key) { - return appendCommand(commandObjects.zpopmax(key)); - } - - @Override - public Response> zpopmax(String key, int count) { - return appendCommand(commandObjects.zpopmax(key, count)); - } - - @Override - public Response zpopmin(String key) { - return appendCommand(commandObjects.zpopmin(key)); - } - - @Override - public Response> zpopmin(String key, int count) { - return appendCommand(commandObjects.zpopmin(key, count)); - } - - @Override - public Response zcount(String key, double min, double max) { - return appendCommand(commandObjects.zcount(key, min, max)); - } - - @Override - public Response zcount(String key, String min, String max) { - return appendCommand(commandObjects.zcount(key, min, max)); - } - - @Override - public Response> zrangeByScore(String key, double min, double max) { - return appendCommand(commandObjects.zrangeByScore(key, min, max)); - } - - @Override - public Response> zrangeByScore(String key, String min, String max) { - return appendCommand(commandObjects.zrangeByScore(key, min, max)); - } - - @Override - public Response> zrevrangeByScore(String key, double max, double min) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); - } - - @Override - public Response> zrangeByScore(String key, double min, double max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(String key, String max, String min) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); - } - - @Override - public Response> zrangeByScore(String key, String min, String max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(String key, double max, double min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); - } - - @Override - public Response> zrangeByScoreWithScores(String key, double min, double max) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); - } - - @Override - public Response> zrevrangeByScoreWithScores(String key, double max, double min) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); - } - - @Override - public Response> zrangeByScoreWithScores(String key, double min, double max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(String key, String max, String min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); - } - - @Override - public Response> zrangeByScoreWithScores(String key, String min, String max) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); - } - - @Override - public Response> zrevrangeByScoreWithScores(String key, String max, String min) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); - } - - @Override - public Response> zrangeByScoreWithScores(String key, String min, String max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScoreWithScores(String key, double max, double min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); - } - - @Override - public Response> zrevrangeByScoreWithScores(String key, String max, String min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); - } - - @Override - public Response> zrange(String key, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrange(key, zRangeParams)); - } - - @Override - public Response> zrangeWithScores(String key, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrangeWithScores(key, zRangeParams)); - } - - @Override - public Response zrangestore(String dest, String src, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrangestore(dest, src, zRangeParams)); - } - - @Override - public Response zremrangeByRank(String key, long start, long stop) { - return appendCommand(commandObjects.zremrangeByRank(key, start, stop)); - } - - @Override - public Response zremrangeByScore(String key, double min, double max) { - return appendCommand(commandObjects.zremrangeByScore(key, min, max)); - } - - @Override - public Response zremrangeByScore(String key, String min, String max) { - return appendCommand(commandObjects.zremrangeByScore(key, min, max)); - } - - @Override - public Response zlexcount(String key, String min, String max) { - return appendCommand(commandObjects.zlexcount(key, min, max)); - } - - @Override - public Response> zrangeByLex(String key, String min, String max) { - return appendCommand(commandObjects.zrangeByLex(key, min, max)); - } - - @Override - public Response> zrangeByLex(String key, String min, String max, int offset, int count) { - return appendCommand(commandObjects.zrangeByLex(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByLex(String key, String max, String min) { - return appendCommand(commandObjects.zrevrangeByLex(key, max, min)); - } - - @Override - public Response> zrevrangeByLex(String key, String max, String min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByLex(key, max, min, offset, count)); - } - - @Override - public Response zremrangeByLex(String key, String min, String max) { - return appendCommand(commandObjects.zremrangeByLex(key, min, max)); - } - - @Override - public Response> zscan(String key, String cursor, ScanParams params) { - return appendCommand(commandObjects.zscan(key, cursor, params)); - } - - @Override - public Response> bzpopmax(double timeout, String... keys) { - return appendCommand(commandObjects.bzpopmax(timeout, keys)); - } - - @Override - public Response> bzpopmin(double timeout, String... keys) { - return appendCommand(commandObjects.bzpopmin(timeout, keys)); - } - - @Override - public Response>> zmpop(SortedSetOption option, String... keys) { - return appendCommand(commandObjects.zmpop(option, keys)); - } - - @Override - public Response>> zmpop(SortedSetOption option, int count, String... keys) { - return appendCommand(commandObjects.zmpop(option, count, keys)); - } - - @Override - public Response>> bzmpop(double timeout, SortedSetOption option, String... keys) { - return appendCommand(commandObjects.bzmpop(timeout, option, keys)); - } - - @Override - public Response>> bzmpop(double timeout, SortedSetOption option, int count, String... keys) { - return appendCommand(commandObjects.bzmpop(timeout, option, count, keys)); - } - - @Override - public Response> zdiff(String... keys) { - return appendCommand(commandObjects.zdiff(keys)); - } - - @Override - public Response> zdiffWithScores(String... keys) { - return appendCommand(commandObjects.zdiffWithScores(keys)); - } - - @Override - @Deprecated - public Response zdiffStore(String dstKey, String... keys) { - return appendCommand(commandObjects.zdiffStore(dstKey, keys)); - } - - @Override - public Response zdiffstore(String dstKey, String... keys) { - return appendCommand(commandObjects.zdiffstore(dstKey, keys)); - } - - @Override - public Response zinterstore(String dstKey, String... sets) { - return appendCommand(commandObjects.zinterstore(dstKey, sets)); - } - - @Override - public Response zinterstore(String dstKey, ZParams params, String... sets) { - return appendCommand(commandObjects.zinterstore(dstKey, params, sets)); - } - - @Override - public Response> zinter(ZParams params, String... keys) { - return appendCommand(commandObjects.zinter(params, keys)); - } - - @Override - public Response> zinterWithScores(ZParams params, String... keys) { - return appendCommand(commandObjects.zinterWithScores(params, keys)); - } - - @Override - public Response zintercard(String... keys) { - return appendCommand(commandObjects.zintercard(keys)); - } - - @Override - public Response zintercard(long limit, String... keys) { - return appendCommand(commandObjects.zintercard(limit, keys)); - } - - @Override - public Response> zunion(ZParams params, String... keys) { - return appendCommand(commandObjects.zunion(params, keys)); - } - - @Override - public Response> zunionWithScores(ZParams params, String... keys) { - return appendCommand(commandObjects.zunionWithScores(params, keys)); - } - - @Override - public Response zunionstore(String dstKey, String... sets) { - return appendCommand(commandObjects.zunionstore(dstKey, sets)); - } - - @Override - public Response zunionstore(String dstKey, ZParams params, String... sets) { - return appendCommand(commandObjects.zunionstore(dstKey, params, sets)); - } - - @Override - public Response geoadd(String key, double longitude, double latitude, String member) { - return appendCommand(commandObjects.geoadd(key, longitude, latitude, member)); - } - - @Override - public Response geoadd(String key, Map memberCoordinateMap) { - return appendCommand(commandObjects.geoadd(key, memberCoordinateMap)); - } - - @Override - public Response geoadd(String key, GeoAddParams params, Map memberCoordinateMap) { - return appendCommand(commandObjects.geoadd(key, params, memberCoordinateMap)); - } - - @Override - public Response geodist(String key, String member1, String member2) { - return appendCommand(commandObjects.geodist(key, member1, member2)); - } - - @Override - public Response geodist(String key, String member1, String member2, GeoUnit unit) { - return appendCommand(commandObjects.geodist(key, member1, member2, unit)); - } - - @Override - public Response> geohash(String key, String... members) { - return appendCommand(commandObjects.geohash(key, members)); - } - - @Override - public Response> geopos(String key, String... members) { - return appendCommand(commandObjects.geopos(key, members)); - } - - @Override - public Response> georadius(String key, double longitude, double latitude, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit)); - } - - @Override - public Response> georadiusReadonly(String key, double longitude, double latitude, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit)); - } - - @Override - public Response> georadius(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit, param)); - } - - @Override - public Response> georadiusReadonly(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit, param)); - } - - @Override - public Response> georadiusByMember(String key, String member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit)); - } - - @Override - public Response> georadiusByMemberReadonly(String key, String member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit)); - } - - @Override - public Response> georadiusByMember(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit, param)); - } - - @Override - public Response> georadiusByMemberReadonly(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit, param)); - } - - @Override - public Response georadiusStore(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { - return appendCommand(commandObjects.georadiusStore(key, longitude, latitude, radius, unit, param, storeParam)); - } - - @Override - public Response georadiusByMemberStore(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { - return appendCommand(commandObjects.georadiusByMemberStore(key, member, radius, unit, param, storeParam)); - } - - @Override - public Response> geosearch(String key, String member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, member, radius, unit)); - } - - @Override - public Response> geosearch(String key, GeoCoordinate coord, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, coord, radius, unit)); - } - - @Override - public Response> geosearch(String key, String member, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, member, width, height, unit)); - } - - @Override - public Response> geosearch(String key, GeoCoordinate coord, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, coord, width, height, unit)); - } - - @Override - public Response> geosearch(String key, GeoSearchParam params) { - return appendCommand(commandObjects.geosearch(key, params)); - } - - @Override - public Response geosearchStore(String dest, String src, String member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, member, radius, unit)); - } - - @Override - public Response geosearchStore(String dest, String src, GeoCoordinate coord, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, coord, radius, unit)); - } - - @Override - public Response geosearchStore(String dest, String src, String member, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, member, width, height, unit)); - } - - @Override - public Response geosearchStore(String dest, String src, GeoCoordinate coord, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, coord, width, height, unit)); - } - - @Override - public Response geosearchStore(String dest, String src, GeoSearchParam params) { - return appendCommand(commandObjects.geosearchStore(dest, src, params)); - } - - @Override - public Response geosearchStoreStoreDist(String dest, String src, GeoSearchParam params) { - return appendCommand(commandObjects.geosearchStoreStoreDist(dest, src, params)); - } - - @Override - public Response pfadd(String key, String... elements) { - return appendCommand(commandObjects.pfadd(key, elements)); - } - - @Override - public Response pfmerge(String destkey, String... sourcekeys) { - return appendCommand(commandObjects.pfmerge(destkey, sourcekeys)); - } - - @Override - public Response pfcount(String key) { - return appendCommand(commandObjects.pfcount(key)); - } - - @Override - public Response pfcount(String... keys) { - return appendCommand(commandObjects.pfcount(keys)); - } - - @Override - public Response xadd(String key, StreamEntryID id, Map hash) { - return appendCommand(commandObjects.xadd(key, id, hash)); - } - - @Override - public Response xadd(String key, XAddParams params, Map hash) { - return appendCommand(commandObjects.xadd(key, params, hash)); - } - - @Override - public Response xlen(String key) { - return appendCommand(commandObjects.xlen(key)); - } - - @Override - public Response> xrange(String key, StreamEntryID start, StreamEntryID end) { - return appendCommand(commandObjects.xrange(key, start, end)); - } - - @Override - public Response> xrange(String key, StreamEntryID start, StreamEntryID end, int count) { - return appendCommand(commandObjects.xrange(key, start, end, count)); - } - - @Override - public Response> xrevrange(String key, StreamEntryID end, StreamEntryID start) { - return appendCommand(commandObjects.xrevrange(key, end, start)); - } - - @Override - public Response> xrevrange(String key, StreamEntryID end, StreamEntryID start, int count) { - return appendCommand(commandObjects.xrevrange(key, end, start, count)); - } - - @Override - public Response> xrange(String key, String start, String end) { - return appendCommand(commandObjects.xrange(key, start, end)); - } - - @Override - public Response> xrange(String key, String start, String end, int count) { - return appendCommand(commandObjects.xrange(key, start, end, count)); - } - - @Override - public Response> xrevrange(String key, String end, String start) { - return appendCommand(commandObjects.xrevrange(key, end, start)); - } - - @Override - public Response> xrevrange(String key, String end, String start, int count) { - return appendCommand(commandObjects.xrevrange(key, end, start, count)); - } - - @Override - public Response xack(String key, String group, StreamEntryID... ids) { - return appendCommand(commandObjects.xack(key, group, ids)); - } - - @Override - public Response xgroupCreate(String key, String groupName, StreamEntryID id, boolean makeStream) { - return appendCommand(commandObjects.xgroupCreate(key, groupName, id, makeStream)); - } - - @Override - public Response xgroupSetID(String key, String groupName, StreamEntryID id) { - return appendCommand(commandObjects.xgroupSetID(key, groupName, id)); - } - - @Override - public Response xgroupDestroy(String key, String groupName) { - return appendCommand(commandObjects.xgroupDestroy(key, groupName)); - } - - @Override - public Response xgroupCreateConsumer(String key, String groupName, String consumerName) { - return appendCommand(commandObjects.xgroupCreateConsumer(key, groupName, consumerName)); - } - - @Override - public Response xgroupDelConsumer(String key, String groupName, String consumerName) { - return appendCommand(commandObjects.xgroupDelConsumer(key, groupName, consumerName)); - } - - @Override - public Response xpending(String key, String groupName) { - return appendCommand(commandObjects.xpending(key, groupName)); - } - - @Override - public Response> xpending(String key, String groupName, XPendingParams params) { - return appendCommand(commandObjects.xpending(key, groupName, params)); - } - - @Override - public Response xdel(String key, StreamEntryID... ids) { - return appendCommand(commandObjects.xdel(key, ids)); - } - - @Override - public Response xtrim(String key, long maxLen, boolean approximate) { - return appendCommand(commandObjects.xtrim(key, maxLen, approximate)); - } - - @Override - public Response xtrim(String key, XTrimParams params) { - return appendCommand(commandObjects.xtrim(key, params)); - } - - @Override - public Response> xclaim(String key, String group, String consumerName, long minIdleTime, XClaimParams params, StreamEntryID... ids) { - return appendCommand(commandObjects.xclaim(key, group, consumerName, minIdleTime, params, ids)); - } - - @Override - public Response> xclaimJustId(String key, String group, String consumerName, long minIdleTime, XClaimParams params, StreamEntryID... ids) { - return appendCommand(commandObjects.xclaimJustId(key, group, consumerName, minIdleTime, params, ids)); - } - - @Override - public Response>> xautoclaim(String key, String group, String consumerName, long minIdleTime, StreamEntryID start, XAutoClaimParams params) { - return appendCommand(commandObjects.xautoclaim(key, group, consumerName, minIdleTime, start, params)); - } - - @Override - public Response>> xautoclaimJustId(String key, String group, String consumerName, long minIdleTime, StreamEntryID start, XAutoClaimParams params) { - return appendCommand(commandObjects.xautoclaimJustId(key, group, consumerName, minIdleTime, start, params)); - } - - @Override - public Response xinfoStream(String key) { - return appendCommand(commandObjects.xinfoStream(key)); - } - - @Override - public Response xinfoStreamFull(String key) { - return appendCommand(commandObjects.xinfoStreamFull(key)); - } - - @Override - public Response xinfoStreamFull(String key, int count) { - return appendCommand(commandObjects.xinfoStreamFull(key, count)); - } - - @Override - public Response> xinfoGroups(String key) { - return appendCommand(commandObjects.xinfoGroups(key)); - } - - @Override - public Response> xinfoConsumers(String key, String group) { - return appendCommand(commandObjects.xinfoConsumers(key, group)); - } - - @Override - public Response> xinfoConsumers2(String key, String group) { - return appendCommand(commandObjects.xinfoConsumers2(key, group)); - } - - @Override - public Response>>> xread(XReadParams xReadParams, Map streams) { - return appendCommand(commandObjects.xread(xReadParams, streams)); - } - - @Override - public Response>>> xreadGroup(String groupName, String consumer, XReadGroupParams xReadGroupParams, Map streams) { - return appendCommand(commandObjects.xreadGroup(groupName, consumer, xReadGroupParams, streams)); - } - - @Override - public Response eval(String script) { - return appendCommand(commandObjects.eval(script)); - } - - @Override - public Response eval(String script, int keyCount, String... params) { - return appendCommand(commandObjects.eval(script, keyCount, params)); - } - - @Override - public Response eval(String script, List keys, List args) { - return appendCommand(commandObjects.eval(script, keys, args)); - } - - @Override - public Response evalReadonly(String script, List keys, List args) { - return appendCommand(commandObjects.evalReadonly(script, keys, args)); - } - - @Override - public Response evalsha(String sha1) { - return appendCommand(commandObjects.evalsha(sha1)); - } - - @Override - public Response evalsha(String sha1, int keyCount, String... params) { - return appendCommand(commandObjects.evalsha(sha1, keyCount, params)); - } - - @Override - public Response evalsha(String sha1, List keys, List args) { - return appendCommand(commandObjects.evalsha(sha1, keys, args)); - } - - @Override - public Response evalshaReadonly(String sha1, List keys, List args) { - return appendCommand(commandObjects.evalshaReadonly(sha1, keys, args)); - } - - @Override - public Response waitReplicas(String sampleKey, int replicas, long timeout) { - return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout)); - } - - @Override - public Response> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout) { - return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout)); - } - - @Override - public Response eval(String script, String sampleKey) { - return appendCommand(commandObjects.eval(script, sampleKey)); - } - - @Override - public Response evalsha(String sha1, String sampleKey) { - return appendCommand(commandObjects.evalsha(sha1, sampleKey)); - } - - @Override - public Response> scriptExists(String sampleKey, String... sha1) { - return appendCommand(commandObjects.scriptExists(sampleKey, sha1)); - } - - @Override - public Response scriptLoad(String script, String sampleKey) { - return appendCommand(commandObjects.scriptLoad(script, sampleKey)); - } - - @Override - public Response scriptFlush(String sampleKey) { - return appendCommand(commandObjects.scriptFlush(sampleKey)); - } - - @Override - public Response scriptFlush(String sampleKey, FlushMode flushMode) { - return appendCommand(commandObjects.scriptFlush(sampleKey, flushMode)); - } - - @Override - public Response scriptKill(String sampleKey) { - return appendCommand(commandObjects.scriptKill(sampleKey)); - } - - @Override - public Response fcall(byte[] name, List keys, List args) { - return appendCommand(commandObjects.fcall(name, keys, args)); - } - - @Override - public Response fcall(String name, List keys, List args) { - return appendCommand(commandObjects.fcall(name, keys, args)); - } - - @Override - public Response fcallReadonly(byte[] name, List keys, List args) { - return appendCommand(commandObjects.fcallReadonly(name, keys, args)); - } - - @Override - public Response fcallReadonly(String name, List keys, List args) { - return appendCommand(commandObjects.fcallReadonly(name, keys, args)); - } - - @Override - public Response functionDelete(byte[] libraryName) { - return appendCommand(commandObjects.functionDelete(libraryName)); - } - - @Override - public Response functionDelete(String libraryName) { - return appendCommand(commandObjects.functionDelete(libraryName)); - } - - @Override - public Response functionDump() { - return appendCommand(commandObjects.functionDump()); - } - - @Override - public Response> functionList(String libraryNamePattern) { - return appendCommand(commandObjects.functionList(libraryNamePattern)); - } - - @Override - public Response> functionList() { - return appendCommand(commandObjects.functionList()); - } - - @Override - public Response> functionListWithCode(String libraryNamePattern) { - return appendCommand(commandObjects.functionListWithCode(libraryNamePattern)); - } - - @Override - public Response> functionListWithCode() { - return appendCommand(commandObjects.functionListWithCode()); - } - - @Override - public Response> functionListBinary() { - return appendCommand(commandObjects.functionListBinary()); - } - - @Override - public Response> functionList(final byte[] libraryNamePattern) { - return appendCommand(commandObjects.functionList(libraryNamePattern)); - } - - @Override - public Response> functionListWithCodeBinary() { - return appendCommand(commandObjects.functionListWithCodeBinary()); - } - - @Override - public Response> functionListWithCode(final byte[] libraryNamePattern) { - return appendCommand(commandObjects.functionListWithCode(libraryNamePattern)); - } - - @Override - public Response functionLoad(byte[] functionCode) { - return appendCommand(commandObjects.functionLoad(functionCode)); - } - - @Override - public Response functionLoad(String functionCode) { - return appendCommand(commandObjects.functionLoad(functionCode)); - } - - @Override - public Response functionLoadReplace(byte[] functionCode) { - return appendCommand(commandObjects.functionLoadReplace(functionCode)); - } - - @Override - public Response functionLoadReplace(String functionCode) { - return appendCommand(commandObjects.functionLoadReplace(functionCode)); - } - - @Override - public Response functionRestore(byte[] serializedValue) { - return appendCommand(commandObjects.functionRestore(serializedValue)); - } - - @Override - public Response functionRestore(byte[] serializedValue, FunctionRestorePolicy policy) { - return appendCommand(commandObjects.functionRestore(serializedValue, policy)); - } - - @Override - public Response functionFlush() { - return appendCommand(commandObjects.functionFlush()); - } - - @Override - public Response functionFlush(FlushMode mode) { - return appendCommand(commandObjects.functionFlush(mode)); - } - - @Override - public Response functionKill() { - return appendCommand(commandObjects.functionKill()); - } - - @Override - public Response functionStats() { - return appendCommand(commandObjects.functionStats()); - } - - @Override - public Response functionStatsBinary() { - return appendCommand(commandObjects.functionStatsBinary()); - } - - @Override - public Response geoadd(byte[] key, double longitude, double latitude, byte[] member) { - return appendCommand(commandObjects.geoadd(key, longitude, latitude, member)); - } - - @Override - public Response geoadd(byte[] key, Map memberCoordinateMap) { - return appendCommand(commandObjects.geoadd(key, memberCoordinateMap)); - } - - @Override - public Response geoadd(byte[] key, GeoAddParams params, Map memberCoordinateMap) { - return appendCommand(commandObjects.geoadd(key, params, memberCoordinateMap)); - } - - @Override - public Response geodist(byte[] key, byte[] member1, byte[] member2) { - return appendCommand(commandObjects.geodist(key, member1, member2)); - } - - @Override - public Response geodist(byte[] key, byte[] member1, byte[] member2, GeoUnit unit) { - return appendCommand(commandObjects.geodist(key, member1, member2, unit)); - } - - @Override - public Response> geohash(byte[] key, byte[]... members) { - return appendCommand(commandObjects.geohash(key, members)); - } - - @Override - public Response> geopos(byte[] key, byte[]... members) { - return appendCommand(commandObjects.geopos(key, members)); - } - - @Override - public Response> georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit)); - } - - @Override - public Response> georadiusReadonly(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit)); - } - - @Override - public Response> georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit, param)); - } - - @Override - public Response> georadiusReadonly(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit, param)); - } - - @Override - public Response> georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit)); - } - - @Override - public Response> georadiusByMemberReadonly(byte[] key, byte[] member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit)); - } - - @Override - public Response> georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit, param)); - } - - @Override - public Response> georadiusByMemberReadonly(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit, param)); - } - - @Override - public Response georadiusStore(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { - return appendCommand(commandObjects.georadiusStore(key, longitude, latitude, radius, unit, param, storeParam)); - } - - @Override - public Response georadiusByMemberStore(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { - return appendCommand(commandObjects.georadiusByMemberStore(key, member, radius, unit, param, storeParam)); - } - - @Override - public Response> geosearch(byte[] key, byte[] member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, member, radius, unit)); - } - - @Override - public Response> geosearch(byte[] key, GeoCoordinate coord, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, coord, radius, unit)); - } - - @Override - public Response> geosearch(byte[] key, byte[] member, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, member, width, height, unit)); - } - - @Override - public Response> geosearch(byte[] key, GeoCoordinate coord, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, coord, width, height, unit)); - } - - @Override - public Response> geosearch(byte[] key, GeoSearchParam params) { - return appendCommand(commandObjects.geosearch(key, params)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, byte[] member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, member, radius, unit)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, GeoCoordinate coord, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, coord, radius, unit)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, byte[] member, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, member, width, height, unit)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, GeoCoordinate coord, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, coord, width, height, unit)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, GeoSearchParam params) { - return appendCommand(commandObjects.geosearchStore(dest, src, params)); - } - - @Override - public Response geosearchStoreStoreDist(byte[] dest, byte[] src, GeoSearchParam params) { - return appendCommand(commandObjects.geosearchStoreStoreDist(dest, src, params)); - } - - @Override - public Response hset(byte[] key, byte[] field, byte[] value) { - return appendCommand(commandObjects.hset(key, field, value)); - } - - @Override - public Response hset(byte[] key, Map hash) { - return appendCommand(commandObjects.hset(key, hash)); - } - - @Override - public Response hget(byte[] key, byte[] field) { - return appendCommand(commandObjects.hget(key, field)); - } - - @Override - public Response hsetnx(byte[] key, byte[] field, byte[] value) { - return appendCommand(commandObjects.hsetnx(key, field, value)); - } - - @Override - public Response hmset(byte[] key, Map hash) { - return appendCommand(commandObjects.hmset(key, hash)); - } - - @Override - public Response> hmget(byte[] key, byte[]... fields) { - return appendCommand(commandObjects.hmget(key, fields)); - } - - @Override - public Response hincrBy(byte[] key, byte[] field, long value) { - return appendCommand(commandObjects.hincrBy(key, field, value)); - } - - @Override - public Response hincrByFloat(byte[] key, byte[] field, double value) { - return appendCommand(commandObjects.hincrByFloat(key, field, value)); - } - - @Override - public Response hexists(byte[] key, byte[] field) { - return appendCommand(commandObjects.hexists(key, field)); - } - - @Override - public Response hdel(byte[] key, byte[]... field) { - return appendCommand(commandObjects.hdel(key, field)); - } - - @Override - public Response hlen(byte[] key) { - return appendCommand(commandObjects.hlen(key)); - } - - @Override - public Response> hkeys(byte[] key) { - return appendCommand(commandObjects.hkeys(key)); - } - - @Override - public Response> hvals(byte[] key) { - return appendCommand(commandObjects.hvals(key)); - } - - @Override - public Response> hgetAll(byte[] key) { - return appendCommand(commandObjects.hgetAll(key)); - } - - @Override - public Response hrandfield(byte[] key) { - return appendCommand(commandObjects.hrandfield(key)); - } - - @Override - public Response> hrandfield(byte[] key, long count) { - return appendCommand(commandObjects.hrandfield(key, count)); - } - - @Override - public Response>> hrandfieldWithValues(byte[] key, long count) { - return appendCommand(commandObjects.hrandfieldWithValues(key, count)); - } - - @Override - public Response>> hscan(byte[] key, byte[] cursor, ScanParams params) { - return appendCommand(commandObjects.hscan(key, cursor, params)); - } - - @Override - public Response hstrlen(byte[] key, byte[] field) { - return appendCommand(commandObjects.hstrlen(key, field)); - } - - @Override - public Response pfadd(byte[] key, byte[]... elements) { - return appendCommand(commandObjects.pfadd(key, elements)); - } - - @Override - public Response pfmerge(byte[] destkey, byte[]... sourcekeys) { - return appendCommand(commandObjects.pfmerge(destkey, sourcekeys)); - } - - @Override - public Response pfcount(byte[] key) { - return appendCommand(commandObjects.pfcount(key)); - } - - @Override - public Response pfcount(byte[]... keys) { - return appendCommand(commandObjects.pfcount(keys)); - } - - @Override - public Response exists(byte[] key) { - return appendCommand(commandObjects.exists(key)); - } - - @Override - public Response exists(byte[]... keys) { - return appendCommand(commandObjects.exists(keys)); - } - - @Override - public Response persist(byte[] key) { - return appendCommand(commandObjects.persist(key)); - } - - @Override - public Response type(byte[] key) { - return appendCommand(commandObjects.type(key)); - } - - @Override - public Response dump(byte[] key) { - return appendCommand(commandObjects.dump(key)); - } - - @Override - public Response restore(byte[] key, long ttl, byte[] serializedValue) { - return appendCommand(commandObjects.restore(key, ttl, serializedValue)); - } - - @Override - public Response restore(byte[] key, long ttl, byte[] serializedValue, RestoreParams params) { - return appendCommand(commandObjects.restore(key, ttl, serializedValue, params)); - } - - @Override - public Response expire(byte[] key, long seconds) { - return appendCommand(commandObjects.expire(key, seconds)); - } - - @Override - public Response expire(byte[] key, long seconds, ExpiryOption expiryOption) { - return appendCommand(commandObjects.expire(key, seconds, expiryOption)); - } - - @Override - public Response pexpire(byte[] key, long milliseconds) { - return appendCommand(commandObjects.pexpire(key, milliseconds)); - } - - @Override - public Response pexpire(byte[] key, long milliseconds, ExpiryOption expiryOption) { - return appendCommand(commandObjects.pexpire(key, milliseconds, expiryOption)); - } - - @Override - public Response expireTime(byte[] key) { - return appendCommand(commandObjects.expireTime(key)); - } - - @Override - public Response pexpireTime(byte[] key) { - return appendCommand(commandObjects.pexpireTime(key)); - } - - @Override - public Response expireAt(byte[] key, long unixTime) { - return appendCommand(commandObjects.expireAt(key, unixTime)); - } - - @Override - public Response expireAt(byte[] key, long unixTime, ExpiryOption expiryOption) { - return appendCommand(commandObjects.expireAt(key, unixTime)); - } - - @Override - public Response pexpireAt(byte[] key, long millisecondsTimestamp) { - return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp)); - } - - @Override - public Response pexpireAt(byte[] key, long millisecondsTimestamp, ExpiryOption expiryOption) { - return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp, expiryOption)); - } - - @Override - public Response ttl(byte[] key) { - return appendCommand(commandObjects.ttl(key)); - } - - @Override - public Response pttl(byte[] key) { - return appendCommand(commandObjects.pttl(key)); - } - - @Override - public Response touch(byte[] key) { - return appendCommand(commandObjects.touch(key)); - } - - @Override - public Response touch(byte[]... keys) { - return appendCommand(commandObjects.touch(keys)); - } - - @Override - public Response> sort(byte[] key) { - return appendCommand(commandObjects.sort(key)); - } - - @Override - public Response> sort(byte[] key, SortingParams sortingParams) { - return appendCommand(commandObjects.sort(key, sortingParams)); - } - - @Override - public Response> sortReadonly(byte[] key, SortingParams sortingParams) { - return appendCommand(commandObjects.sortReadonly(key, sortingParams)); - } - - @Override - public Response del(byte[] key) { - return appendCommand(commandObjects.del(key)); - } - - @Override - public Response del(byte[]... keys) { - return appendCommand(commandObjects.del(keys)); - } - - @Override - public Response unlink(byte[] key) { - return appendCommand(commandObjects.unlink(key)); - } - - @Override - public Response unlink(byte[]... keys) { - return appendCommand(commandObjects.unlink(keys)); - } - - @Override - public Response copy(byte[] srcKey, byte[] dstKey, boolean replace) { - return appendCommand(commandObjects.copy(srcKey, dstKey, replace)); - } - - @Override - public Response rename(byte[] oldkey, byte[] newkey) { - return appendCommand(commandObjects.rename(oldkey, newkey)); - } - - @Override - public Response renamenx(byte[] oldkey, byte[] newkey) { - return appendCommand(commandObjects.renamenx(oldkey, newkey)); - } - - @Override - public Response sort(byte[] key, SortingParams sortingParams, byte[] dstkey) { - return appendCommand(commandObjects.sort(key, sortingParams, dstkey)); - } - - @Override - public Response sort(byte[] key, byte[] dstkey) { - return appendCommand(commandObjects.sort(key, dstkey)); - } - - @Override - public Response memoryUsage(byte[] key) { - return appendCommand(commandObjects.memoryUsage(key)); - } - - @Override - public Response memoryUsage(byte[] key, int samples) { - return appendCommand(commandObjects.memoryUsage(key, samples)); - } - - @Override - public Response objectRefcount(byte[] key) { - return appendCommand(commandObjects.objectRefcount(key)); - } - - @Override - public Response objectEncoding(byte[] key) { - return appendCommand(commandObjects.objectEncoding(key)); - } - - @Override - public Response objectIdletime(byte[] key) { - return appendCommand(commandObjects.objectIdletime(key)); - } - - @Override - public Response objectFreq(byte[] key) { - return appendCommand(commandObjects.objectFreq(key)); - } - - @Override - public Response migrate(String host, int port, byte[] key, int timeout) { - return appendCommand(commandObjects.migrate(host, port, key, timeout)); - } - - @Override - public Response migrate(String host, int port, int timeout, MigrateParams params, byte[]... keys) { - return appendCommand(commandObjects.migrate(host, port, timeout, params, keys)); - } - - @Override - public Response> keys(byte[] pattern) { - return appendCommand(commandObjects.keys(pattern)); - } - - @Override - public Response> scan(byte[] cursor) { - return appendCommand(commandObjects.scan(cursor)); - } - - @Override - public Response> scan(byte[] cursor, ScanParams params) { - return appendCommand(commandObjects.scan(cursor, params)); - } - - @Override - public Response> scan(byte[] cursor, ScanParams params, byte[] type) { - return appendCommand(commandObjects.scan(cursor, params, type)); - } - - @Override - public Response randomBinaryKey() { - return appendCommand(commandObjects.randomBinaryKey()); - } - - @Override - public Response rpush(byte[] key, byte[]... args) { - return appendCommand(commandObjects.rpush(key, args)); - } - - @Override - public Response lpush(byte[] key, byte[]... args) { - return appendCommand(commandObjects.lpush(key, args)); - } - - @Override - public Response llen(byte[] key) { - return appendCommand(commandObjects.llen(key)); - } - - @Override - public Response> lrange(byte[] key, long start, long stop) { - return appendCommand(commandObjects.lrange(key, start, stop)); - } - - @Override - public Response ltrim(byte[] key, long start, long stop) { - return appendCommand(commandObjects.ltrim(key, start, stop)); - } - - @Override - public Response lindex(byte[] key, long index) { - return appendCommand(commandObjects.lindex(key, index)); - } - - @Override - public Response lset(byte[] key, long index, byte[] value) { - return appendCommand(commandObjects.lset(key, index, value)); - } - - @Override - public Response lrem(byte[] key, long count, byte[] value) { - return appendCommand(commandObjects.lrem(key, count, value)); - } - - @Override - public Response lpop(byte[] key) { - return appendCommand(commandObjects.lpop(key)); - } - - @Override - public Response> lpop(byte[] key, int count) { - return appendCommand(commandObjects.lpop(key, count)); - } - - @Override - public Response lpos(byte[] key, byte[] element) { - return appendCommand(commandObjects.lpos(key, element)); - } - - @Override - public Response lpos(byte[] key, byte[] element, LPosParams params) { - return appendCommand(commandObjects.lpos(key, element, params)); - } - - @Override - public Response> lpos(byte[] key, byte[] element, LPosParams params, long count) { - return appendCommand(commandObjects.lpos(key, element, params, count)); - } - - @Override - public Response rpop(byte[] key) { - return appendCommand(commandObjects.rpop(key)); - } - - @Override - public Response> rpop(byte[] key, int count) { - return appendCommand(commandObjects.rpop(key, count)); - } - - @Override - public Response linsert(byte[] key, ListPosition where, byte[] pivot, byte[] value) { - return appendCommand(commandObjects.linsert(key, where, pivot, value)); - } - - @Override - public Response lpushx(byte[] key, byte[]... args) { - return appendCommand(commandObjects.lpushx(key, args)); - } - - @Override - public Response rpushx(byte[] key, byte[]... args) { - return appendCommand(commandObjects.rpushx(key, args)); - } - - @Override - public Response> blpop(int timeout, byte[]... keys) { - return appendCommand(commandObjects.blpop(timeout, keys)); - } - - @Override - public Response> blpop(double timeout, byte[]... keys) { - return appendCommand(commandObjects.blpop(timeout, keys)); - } - - @Override - public Response> brpop(int timeout, byte[]... keys) { - return appendCommand(commandObjects.brpop(timeout, keys)); - } - - @Override - public Response> brpop(double timeout, byte[]... keys) { - return appendCommand(commandObjects.brpop(timeout, keys)); - } - - @Override - public Response rpoplpush(byte[] srckey, byte[] dstkey) { - return appendCommand(commandObjects.rpoplpush(srckey, dstkey)); - } - - @Override - public Response brpoplpush(byte[] source, byte[] destination, int timeout) { - return appendCommand(commandObjects.brpoplpush(source, destination, timeout)); - } - - @Override - public Response lmove(byte[] srcKey, byte[] dstKey, ListDirection from, ListDirection to) { - return appendCommand(commandObjects.lmove(srcKey, dstKey, from, to)); - } - - @Override - public Response blmove(byte[] srcKey, byte[] dstKey, ListDirection from, ListDirection to, double timeout) { - return appendCommand(commandObjects.blmove(srcKey, dstKey, from, to, timeout)); - } - - @Override - public Response>> lmpop(ListDirection direction, byte[]... keys) { - return appendCommand(commandObjects.lmpop(direction, keys)); - } - - @Override - public Response>> lmpop(ListDirection direction, int count, byte[]... keys) { - return appendCommand(commandObjects.lmpop(direction, count, keys)); - } - - @Override - public Response>> blmpop(double timeout, ListDirection direction, byte[]... keys) { - return appendCommand(commandObjects.blmpop(timeout, direction, keys)); - } - - @Override - public Response>> blmpop(double timeout, ListDirection direction, int count, byte[]... keys) { - return appendCommand(commandObjects.blmpop(timeout, direction, count, keys)); - } - - @Override - public Response waitReplicas(byte[] sampleKey, int replicas, long timeout) { - return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout)); - } - - @Override - public Response> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout) { - return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout)); - } - - @Override - public Response eval(byte[] script, byte[] sampleKey) { - return appendCommand(commandObjects.eval(script, sampleKey)); - } - - @Override - public Response evalsha(byte[] sha1, byte[] sampleKey) { - return appendCommand(commandObjects.evalsha(sha1, sampleKey)); - } - - @Override - public Response> scriptExists(byte[] sampleKey, byte[]... sha1s) { - return appendCommand(commandObjects.scriptExists(sampleKey, sha1s)); - } - - @Override - public Response scriptLoad(byte[] script, byte[] sampleKey) { - return appendCommand(commandObjects.scriptLoad(script, sampleKey)); - } - - @Override - public Response scriptFlush(byte[] sampleKey) { - return appendCommand(commandObjects.scriptFlush(sampleKey)); - } - - @Override - public Response scriptFlush(byte[] sampleKey, FlushMode flushMode) { - return appendCommand(commandObjects.scriptFlush(sampleKey, flushMode)); - } - - @Override - public Response scriptKill(byte[] sampleKey) { - return appendCommand(commandObjects.scriptKill(sampleKey)); - } - - @Override - public Response eval(byte[] script) { - return appendCommand(commandObjects.eval(script)); - } - - @Override - public Response eval(byte[] script, int keyCount, byte[]... params) { - return appendCommand(commandObjects.eval(script, keyCount, params)); - } - - @Override - public Response eval(byte[] script, List keys, List args) { - return appendCommand(commandObjects.eval(script, keys, args)); - } - - @Override - public Response evalReadonly(byte[] script, List keys, List args) { - return appendCommand(commandObjects.evalReadonly(script, keys, args)); - } - - @Override - public Response evalsha(byte[] sha1) { - return appendCommand(commandObjects.evalsha(sha1)); - } - - @Override - public Response evalsha(byte[] sha1, int keyCount, byte[]... params) { - return appendCommand(commandObjects.evalsha(sha1, keyCount, params)); - } - - @Override - public Response evalsha(byte[] sha1, List keys, List args) { - return appendCommand(commandObjects.evalsha(sha1, keys, args)); - } - - @Override - public Response evalshaReadonly(byte[] sha1, List keys, List args) { - return appendCommand(commandObjects.evalshaReadonly(sha1, keys, args)); - } - - @Override - public Response sadd(byte[] key, byte[]... members) { - return appendCommand(commandObjects.sadd(key, members)); - } - - @Override - public Response> smembers(byte[] key) { - return appendCommand(commandObjects.smembers(key)); - } - - @Override - public Response srem(byte[] key, byte[]... members) { - return appendCommand(commandObjects.srem(key, members)); - } - - @Override - public Response spop(byte[] key) { - return appendCommand(commandObjects.spop(key)); - } - - @Override - public Response> spop(byte[] key, long count) { - return appendCommand(commandObjects.spop(key, count)); - } - - @Override - public Response scard(byte[] key) { - return appendCommand(commandObjects.scard(key)); - } - - @Override - public Response sismember(byte[] key, byte[] member) { - return appendCommand(commandObjects.sismember(key, member)); - } - - @Override - public Response> smismember(byte[] key, byte[]... members) { - return appendCommand(commandObjects.smismember(key, members)); - } - - @Override - public Response srandmember(byte[] key) { - return appendCommand(commandObjects.srandmember(key)); - } - - @Override - public Response> srandmember(byte[] key, int count) { - return appendCommand(commandObjects.srandmember(key, count)); - } - - @Override - public Response> sscan(byte[] key, byte[] cursor, ScanParams params) { - return appendCommand(commandObjects.sscan(key, cursor, params)); - } - - @Override - public Response> sdiff(byte[]... keys) { - return appendCommand(commandObjects.sdiff(keys)); - } - - @Override - public Response sdiffstore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.sdiffstore(dstkey, keys)); - } - - @Override - public Response> sinter(byte[]... keys) { - return appendCommand(commandObjects.sinter(keys)); - } - - @Override - public Response sinterstore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.sinterstore(dstkey, keys)); - } - - @Override - public Response sintercard(byte[]... keys) { - return appendCommand(commandObjects.sintercard(keys)); - } - - @Override - public Response sintercard(int limit, byte[]... keys) { - return appendCommand(commandObjects.sintercard(limit, keys)); - } - - @Override - public Response> sunion(byte[]... keys) { - return appendCommand(commandObjects.sunion(keys)); - } - - @Override - public Response sunionstore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.sunionstore(dstkey, keys)); - } - - @Override - public Response smove(byte[] srckey, byte[] dstkey, byte[] member) { - return appendCommand(commandObjects.smove(srckey, dstkey, member)); - } - - @Override - public Response zadd(byte[] key, double score, byte[] member) { - return appendCommand(commandObjects.zadd(key, score, member)); - } - - @Override - public Response zadd(byte[] key, double score, byte[] member, ZAddParams params) { - return appendCommand(commandObjects.zadd(key, score, member, params)); - } - - @Override - public Response zadd(byte[] key, Map scoreMembers) { - return appendCommand(commandObjects.zadd(key, scoreMembers)); - } - - @Override - public Response zadd(byte[] key, Map scoreMembers, ZAddParams params) { - return appendCommand(commandObjects.zadd(key, scoreMembers, params)); - } - - @Override - public Response zaddIncr(byte[] key, double score, byte[] member, ZAddParams params) { - return appendCommand(commandObjects.zaddIncr(key, score, member, params)); - } - - @Override - public Response zrem(byte[] key, byte[]... members) { - return appendCommand(commandObjects.zrem(key, members)); - } - - @Override - public Response zincrby(byte[] key, double increment, byte[] member) { - return appendCommand(commandObjects.zincrby(key, increment, member)); - } - - @Override - public Response zincrby(byte[] key, double increment, byte[] member, ZIncrByParams params) { - return appendCommand(commandObjects.zincrby(key, increment, member, params)); - } - - @Override - public Response zrank(byte[] key, byte[] member) { - return appendCommand(commandObjects.zrank(key, member)); - } - - @Override - public Response zrevrank(byte[] key, byte[] member) { - return appendCommand(commandObjects.zrevrank(key, member)); - } - - @Override - public Response> zrankWithScore(byte[] key, byte[] member) { - return appendCommand(commandObjects.zrankWithScore(key, member)); - } - - @Override - public Response> zrevrankWithScore(byte[] key, byte[] member) { - return appendCommand(commandObjects.zrevrankWithScore(key, member)); - } - - @Override - public Response> zrange(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zrange(key, start, stop)); - } - - @Override - public Response> zrevrange(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zrevrange(key, start, stop)); - } - - @Override - public Response> zrangeWithScores(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zrangeWithScores(key, start, stop)); - } - - @Override - public Response> zrevrangeWithScores(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zrevrangeWithScores(key, start, stop)); - } - - @Override - public Response zrandmember(byte[] key) { - return appendCommand(commandObjects.zrandmember(key)); - } - - @Override - public Response> zrandmember(byte[] key, long count) { - return appendCommand(commandObjects.zrandmember(key, count)); - } - - @Override - public Response> zrandmemberWithScores(byte[] key, long count) { - return appendCommand(commandObjects.zrandmemberWithScores(key, count)); - } - - @Override - public Response zcard(byte[] key) { - return appendCommand(commandObjects.zcard(key)); - } - - @Override - public Response zscore(byte[] key, byte[] member) { - return appendCommand(commandObjects.zscore(key, member)); - } - - @Override - public Response> zmscore(byte[] key, byte[]... members) { - return appendCommand(commandObjects.zmscore(key, members)); - } - - @Override - public Response zpopmax(byte[] key) { - return appendCommand(commandObjects.zpopmax(key)); - } - - @Override - public Response> zpopmax(byte[] key, int count) { - return appendCommand(commandObjects.zpopmax(key, count)); - } - - @Override - public Response zpopmin(byte[] key) { - return appendCommand(commandObjects.zpopmin(key)); - } - - @Override - public Response> zpopmin(byte[] key, int count) { - return appendCommand(commandObjects.zpopmin(key, count)); - } - - @Override - public Response zcount(byte[] key, double min, double max) { - return appendCommand(commandObjects.zcount(key, min, max)); - } - - @Override - public Response zcount(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zcount(key, min, max)); - } - - @Override - public Response> zrangeByScore(byte[] key, double min, double max) { - return appendCommand(commandObjects.zrangeByScore(key, min, max)); - } - - @Override - public Response> zrangeByScore(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zrangeByScore(key, min, max)); - } - - @Override - public Response> zrevrangeByScore(byte[] key, double max, double min) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); - } - - @Override - public Response> zrangeByScore(byte[] key, double min, double max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(byte[] key, byte[] max, byte[] min) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); - } - - @Override - public Response> zrangeByScore(byte[] key, byte[] min, byte[] max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(byte[] key, double max, double min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); - } - - @Override - public Response> zrangeByScoreWithScores(byte[] key, double min, double max) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); - } - - @Override - public Response> zrevrangeByScoreWithScores(byte[] key, double max, double min) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); - } - - @Override - public Response> zrangeByScoreWithScores(byte[] key, double min, double max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(byte[] key, byte[] max, byte[] min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); - } - - @Override - public Response> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); - } - - @Override - public Response> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); - } - - @Override - public Response> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScoreWithScores(byte[] key, double max, double min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); - } - - @Override - public Response> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); - } - - @Override - public Response zremrangeByRank(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zremrangeByRank(key, start, stop)); - } - - @Override - public Response zremrangeByScore(byte[] key, double min, double max) { - return appendCommand(commandObjects.zremrangeByScore(key, min, max)); - } - - @Override - public Response zremrangeByScore(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zremrangeByScore(key, min, max)); - } - - @Override - public Response zlexcount(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zlexcount(key, min, max)); - } - - @Override - public Response> zrangeByLex(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zrangeByLex(key, min, max)); - } - - @Override - public Response> zrangeByLex(byte[] key, byte[] min, byte[] max, int offset, int count) { - return appendCommand(commandObjects.zrangeByLex(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByLex(byte[] key, byte[] max, byte[] min) { - return appendCommand(commandObjects.zrevrangeByLex(key, max, min)); - } - - @Override - public Response> zrevrangeByLex(byte[] key, byte[] max, byte[] min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByLex(key, max, min, offset, count)); - } - - @Override - public Response> zrange(byte[] key, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrange(key, zRangeParams)); - } - - @Override - public Response> zrangeWithScores(byte[] key, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrangeWithScores(key, zRangeParams)); - } - - @Override - public Response zrangestore(byte[] dest, byte[] src, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrangestore(dest, src, zRangeParams)); - } - - @Override - public Response zremrangeByLex(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zremrangeByLex(key, min, max)); - } - - @Override - public Response> zscan(byte[] key, byte[] cursor, ScanParams params) { - return appendCommand(commandObjects.zscan(key, cursor, params)); - } - - @Override - public Response> bzpopmax(double timeout, byte[]... keys) { - return appendCommand(commandObjects.bzpopmax(timeout, keys)); - } - - @Override - public Response> bzpopmin(double timeout, byte[]... keys) { - return appendCommand(commandObjects.bzpopmin(timeout, keys)); - } - - @Override - public Response>> zmpop(SortedSetOption option, byte[]... keys) { - return appendCommand(commandObjects.zmpop(option, keys)); - } - - @Override - public Response>> zmpop(SortedSetOption option, int count, byte[]... keys) { - return appendCommand(commandObjects.zmpop(option, count, keys)); - } - - @Override - public Response>> bzmpop(double timeout, SortedSetOption option, byte[]... keys) { - return appendCommand(commandObjects.bzmpop(timeout, option, keys)); - } - - @Override - public Response>> bzmpop(double timeout, SortedSetOption option, int count, byte[]... keys) { - return appendCommand(commandObjects.bzmpop(timeout, option, count, keys)); - } - - @Override - public Response> zdiff(byte[]... keys) { - return appendCommand(commandObjects.zdiff(keys)); - } - - @Override - public Response> zdiffWithScores(byte[]... keys) { - return appendCommand(commandObjects.zdiffWithScores(keys)); - } - - @Override - @Deprecated - public Response zdiffStore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.zdiffStore(dstkey, keys)); - } - - @Override - public Response zdiffstore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.zdiffstore(dstkey, keys)); - } - - @Override - public Response> zinter(ZParams params, byte[]... keys) { - return appendCommand(commandObjects.zinter(params, keys)); - } - - @Override - public Response> zinterWithScores(ZParams params, byte[]... keys) { - return appendCommand(commandObjects.zinterWithScores(params, keys)); - } - - @Override - public Response zinterstore(byte[] dstkey, byte[]... sets) { - return appendCommand(commandObjects.zinterstore(dstkey, sets)); - } - - @Override - public Response zinterstore(byte[] dstkey, ZParams params, byte[]... sets) { - return appendCommand(commandObjects.zinterstore(dstkey, params, sets)); - } - - @Override - public Response zintercard(byte[]... keys) { - return appendCommand(commandObjects.zintercard(keys)); - } - - @Override - public Response zintercard(long limit, byte[]... keys) { - return appendCommand(commandObjects.zintercard(limit, keys)); - } - - @Override - public Response> zunion(ZParams params, byte[]... keys) { - return appendCommand(commandObjects.zunion(params, keys)); - } - - @Override - public Response> zunionWithScores(ZParams params, byte[]... keys) { - return appendCommand(commandObjects.zunionWithScores(params, keys)); - } - - @Override - public Response zunionstore(byte[] dstkey, byte[]... sets) { - return appendCommand(commandObjects.zunionstore(dstkey, sets)); - } - - @Override - public Response zunionstore(byte[] dstkey, ZParams params, byte[]... sets) { - return appendCommand(commandObjects.zunionstore(dstkey, params, sets)); - } - - @Override - public Response xadd(byte[] key, XAddParams params, Map hash) { - return appendCommand(commandObjects.xadd(key, params, hash)); - } - - @Override - public Response xlen(byte[] key) { - return appendCommand(commandObjects.xlen(key)); - } - - @Override - public Response> xrange(byte[] key, byte[] start, byte[] end) { - return appendCommand(commandObjects.xrange(key, start, end)); - } - - @Override - public Response> xrange(byte[] key, byte[] start, byte[] end, int count) { - return appendCommand(commandObjects.xrange(key, start, end, count)); - } - - @Override - public Response> xrevrange(byte[] key, byte[] end, byte[] start) { - return appendCommand(commandObjects.xrevrange(key, end, start)); - } - - @Override - public Response> xrevrange(byte[] key, byte[] end, byte[] start, int count) { - return appendCommand(commandObjects.xrevrange(key, end, start, count)); - } - - @Override - public Response xack(byte[] key, byte[] group, byte[]... ids) { - return appendCommand(commandObjects.xack(key, group, ids)); - } - - @Override - public Response xgroupCreate(byte[] key, byte[] groupName, byte[] id, boolean makeStream) { - return appendCommand(commandObjects.xgroupCreate(key, groupName, id, makeStream)); - } - - @Override - public Response xgroupSetID(byte[] key, byte[] groupName, byte[] id) { - return appendCommand(commandObjects.xgroupSetID(key, groupName, id)); - } - - @Override - public Response xgroupDestroy(byte[] key, byte[] groupName) { - return appendCommand(commandObjects.xgroupDestroy(key, groupName)); - } - - @Override - public Response xgroupCreateConsumer(byte[] key, byte[] groupName, byte[] consumerName) { - return appendCommand(commandObjects.xgroupCreateConsumer(key, groupName, consumerName)); - } - - @Override - public Response xgroupDelConsumer(byte[] key, byte[] groupName, byte[] consumerName) { - return appendCommand(commandObjects.xgroupDelConsumer(key, groupName, consumerName)); - } - - @Override - public Response xdel(byte[] key, byte[]... ids) { - return appendCommand(commandObjects.xdel(key, ids)); - } - - @Override - public Response xtrim(byte[] key, long maxLen, boolean approximateLength) { - return appendCommand(commandObjects.xtrim(key, maxLen, approximateLength)); - } - - @Override - public Response xtrim(byte[] key, XTrimParams params) { - return appendCommand(commandObjects.xtrim(key, params)); - } - - @Override - public Response xpending(byte[] key, byte[] groupName) { - return appendCommand(commandObjects.xpending(key, groupName)); - } - - @Override - public Response> xpending(byte[] key, byte[] groupName, XPendingParams params) { - return appendCommand(commandObjects.xpending(key, groupName, params)); - } - - @Override - public Response> xclaim(byte[] key, byte[] group, byte[] consumerName, long minIdleTime, XClaimParams params, byte[]... ids) { - return appendCommand(commandObjects.xclaim(key, group, consumerName, minIdleTime, params, ids)); - } - - @Override - public Response> xclaimJustId(byte[] key, byte[] group, byte[] consumerName, long minIdleTime, XClaimParams params, byte[]... ids) { - return appendCommand(commandObjects.xclaimJustId(key, group, consumerName, minIdleTime, params, ids)); - } - - @Override - public Response> xautoclaim(byte[] key, byte[] groupName, byte[] consumerName, long minIdleTime, byte[] start, XAutoClaimParams params) { - return appendCommand(commandObjects.xautoclaim(key, groupName, consumerName, minIdleTime, start, params)); - } - - @Override - public Response> xautoclaimJustId(byte[] key, byte[] groupName, byte[] consumerName, long minIdleTime, byte[] start, XAutoClaimParams params) { - return appendCommand(commandObjects.xautoclaimJustId(key, groupName, consumerName, minIdleTime, start, params)); - } - - @Override - public Response xinfoStream(byte[] key) { - return appendCommand(commandObjects.xinfoStream(key)); - } - - @Override - public Response xinfoStreamFull(byte[] key) { - return appendCommand(commandObjects.xinfoStreamFull(key)); - } - - @Override - public Response xinfoStreamFull(byte[] key, int count) { - return appendCommand(commandObjects.xinfoStreamFull(key, count)); - } - - @Override - public Response> xinfoGroups(byte[] key) { - return appendCommand(commandObjects.xinfoGroups(key)); - } - - @Override - public Response> xinfoConsumers(byte[] key, byte[] group) { - return appendCommand(commandObjects.xinfoConsumers(key, group)); - } - - @Override - public Response> xread(XReadParams xReadParams, Map.Entry... streams) { - return appendCommand(commandObjects.xread(xReadParams, streams)); - } - - @Override - public Response> xreadGroup(byte[] groupName, byte[] consumer, XReadGroupParams xReadGroupParams, Map.Entry... streams) { - return appendCommand(commandObjects.xreadGroup(groupName, consumer, xReadGroupParams, streams)); - } - - @Override - public Response set(byte[] key, byte[] value) { - return appendCommand(commandObjects.set(key, value)); - } - - @Override - public Response set(byte[] key, byte[] value, SetParams params) { - return appendCommand(commandObjects.set(key, value, params)); - } - - @Override - public Response get(byte[] key) { - return appendCommand(commandObjects.get(key)); - } - - @Override - public Response setGet(byte[] key, byte[] value, SetParams params) { - return appendCommand(commandObjects.setGet(key, value, params)); - } - - @Override - public Response getDel(byte[] key) { - return appendCommand(commandObjects.getDel(key)); - } - - @Override - public Response getEx(byte[] key, GetExParams params) { - return appendCommand(commandObjects.getEx(key, params)); - } - - @Override - public Response setbit(byte[] key, long offset, boolean value) { - return appendCommand(commandObjects.setbit(key, offset, value)); - } - - @Override - public Response getbit(byte[] key, long offset) { - return appendCommand(commandObjects.getbit(key, offset)); - } - - @Override - public Response setrange(byte[] key, long offset, byte[] value) { - return appendCommand(commandObjects.setrange(key, offset, value)); - } - - @Override - public Response getrange(byte[] key, long startOffset, long endOffset) { - return appendCommand(commandObjects.getrange(key, startOffset, endOffset)); - } - - @Override - public Response getSet(byte[] key, byte[] value) { - return appendCommand(commandObjects.getSet(key, value)); - } - - @Override - public Response setnx(byte[] key, byte[] value) { - return appendCommand(commandObjects.setnx(key, value)); - } - - @Override - public Response setex(byte[] key, long seconds, byte[] value) { - return appendCommand(commandObjects.setex(key, seconds, value)); - } - - @Override - public Response psetex(byte[] key, long milliseconds, byte[] value) { - return appendCommand(commandObjects.psetex(key, milliseconds, value)); - } - - @Override - public Response> mget(byte[]... keys) { - return appendCommand(commandObjects.mget(keys)); - } - - @Override - public Response mset(byte[]... keysvalues) { - return appendCommand(commandObjects.mset(keysvalues)); - } - - @Override - public Response msetnx(byte[]... keysvalues) { - return appendCommand(commandObjects.msetnx(keysvalues)); - } - - @Override - public Response incr(byte[] key) { - return appendCommand(commandObjects.incr(key)); - } - - @Override - public Response incrBy(byte[] key, long increment) { - return appendCommand(commandObjects.incrBy(key, increment)); - } - - @Override - public Response incrByFloat(byte[] key, double increment) { - return appendCommand(commandObjects.incrByFloat(key, increment)); - } - - @Override - public Response decr(byte[] key) { - return appendCommand(commandObjects.decr(key)); - } - - @Override - public Response decrBy(byte[] key, long decrement) { - return appendCommand(commandObjects.decrBy(key, decrement)); - } - - @Override - public Response append(byte[] key, byte[] value) { - return appendCommand(commandObjects.append(key, value)); - } - - @Override - public Response substr(byte[] key, int start, int end) { - return appendCommand(commandObjects.substr(key, start, end)); - } - - @Override - public Response strlen(byte[] key) { - return appendCommand(commandObjects.strlen(key)); - } - - @Override - public Response bitcount(byte[] key) { - return appendCommand(commandObjects.bitcount(key)); - } - - @Override - public Response bitcount(byte[] key, long start, long end) { - return appendCommand(commandObjects.bitcount(key, start, end)); - } - - @Override - public Response bitcount(byte[] key, long start, long end, BitCountOption option) { - return appendCommand(commandObjects.bitcount(key, start, end, option)); - } - - @Override - public Response bitpos(byte[] key, boolean value) { - return appendCommand(commandObjects.bitpos(key, value)); - } - - @Override - public Response bitpos(byte[] key, boolean value, BitPosParams params) { - return appendCommand(commandObjects.bitpos(key, value, params)); - } - - @Override - public Response> bitfield(byte[] key, byte[]... arguments) { - return appendCommand(commandObjects.bitfield(key, arguments)); - } - - @Override - public Response> bitfieldReadonly(byte[] key, byte[]... arguments) { - return appendCommand(commandObjects.bitfieldReadonly(key, arguments)); - } - - @Override - public Response bitop(BitOP op, byte[] destKey, byte[]... srcKeys) { - return appendCommand(commandObjects.bitop(op, destKey, srcKeys)); - } - - // RediSearch commands - @Override - public Response ftCreate(String indexName, IndexOptions indexOptions, Schema schema) { - return appendCommand(commandObjects.ftCreate(indexName, indexOptions, schema)); - } - - @Override - public Response ftCreate(String indexName, FTCreateParams createParams, Iterable schemaFields) { - return appendCommand(commandObjects.ftCreate(indexName, createParams, schemaFields)); - } - - @Override - public Response ftAlter(String indexName, Schema schema) { - return appendCommand(commandObjects.ftAlter(indexName, schema)); - } - - @Override - public Response ftAlter(String indexName, Iterable schemaFields) { - return appendCommand(commandObjects.ftAlter(indexName, schemaFields)); - } - - @Override - public Response ftSearch(String indexName, String query) { - return appendCommand(commandObjects.ftSearch(indexName, query)); - } - - @Override - public Response ftSearch(String indexName, String query, FTSearchParams searchParams) { - return appendCommand(commandObjects.ftSearch(indexName, query, searchParams)); - } - - @Override - public Response ftSearch(String indexName, Query query) { - return appendCommand(commandObjects.ftSearch(indexName, query)); - } - - @Override - @Deprecated - public Response ftSearch(byte[] indexName, Query query) { - return appendCommand(commandObjects.ftSearch(indexName, query)); - } - - @Override - public Response ftExplain(String indexName, Query query) { - return appendCommand(commandObjects.ftExplain(indexName, query)); - } - - @Override - public Response> ftExplainCLI(String indexName, Query query) { - return appendCommand(commandObjects.ftExplainCLI(indexName, query)); - } - - @Override - public Response ftAggregate(String indexName, AggregationBuilder aggr) { - return appendCommand(commandObjects.ftAggregate(indexName, aggr)); - } - - @Override - public Response ftSynUpdate(String indexName, String synonymGroupId, String... terms) { - return appendCommand(commandObjects.ftSynUpdate(indexName, synonymGroupId, terms)); - } - - @Override - public Response>> ftSynDump(String indexName) { - return appendCommand(commandObjects.ftSynDump(indexName)); - } - - @Override - public Response ftDictAdd(String dictionary, String... terms) { - return appendCommand(commandObjects.ftDictAdd(dictionary, terms)); - } - - @Override - public Response ftDictDel(String dictionary, String... terms) { - return appendCommand(commandObjects.ftDictDel(dictionary, terms)); - } - - @Override - public Response> ftDictDump(String dictionary) { - return appendCommand(commandObjects.ftDictDump(dictionary)); - } - - @Override - public Response ftDictAddBySampleKey(String indexName, String dictionary, String... terms) { - return appendCommand(commandObjects.ftDictAddBySampleKey(indexName, dictionary, terms)); - } - - @Override - public Response ftDictDelBySampleKey(String indexName, String dictionary, String... terms) { - return appendCommand(commandObjects.ftDictDelBySampleKey(indexName, dictionary, terms)); - } - - @Override - public Response> ftDictDumpBySampleKey(String indexName, String dictionary) { - return appendCommand(commandObjects.ftDictDumpBySampleKey(indexName, dictionary)); - } - - @Override - public Response>> ftSpellCheck(String index, String query) { - return appendCommand(commandObjects.ftSpellCheck(index, query)); - } - - @Override - public Response>> ftSpellCheck(String index, String query, FTSpellCheckParams spellCheckParams) { - return appendCommand(commandObjects.ftSpellCheck(index, query, spellCheckParams)); - } - - @Override - public Response> ftInfo(String indexName) { - return appendCommand(commandObjects.ftInfo(indexName)); - } - - @Override - public Response> ftTagVals(String indexName, String fieldName) { - return appendCommand(commandObjects.ftTagVals(indexName, fieldName)); - } - - @Override - public Response> ftConfigGet(String option) { - return appendCommand(commandObjects.ftConfigGet(option)); - } - - @Override - public Response> ftConfigGet(String indexName, String option) { - return appendCommand(commandObjects.ftConfigGet(indexName, option)); - } - - @Override - public Response ftConfigSet(String option, String value) { - return appendCommand(commandObjects.ftConfigSet(option, value)); - } - - @Override - public Response ftConfigSet(String indexName, String option, String value) { - return appendCommand(commandObjects.ftConfigSet(indexName, option, value)); - } - - @Override - public Response ftSugAdd(String key, String string, double score) { - return appendCommand(commandObjects.ftSugAdd(key, string, score)); - } - - @Override - public Response ftSugAddIncr(String key, String string, double score) { - return appendCommand(commandObjects.ftSugAddIncr(key, string, score)); - } - - @Override - public Response> ftSugGet(String key, String prefix) { - return appendCommand(commandObjects.ftSugGet(key, prefix)); - } - - @Override - public Response> ftSugGet(String key, String prefix, boolean fuzzy, int max) { - return appendCommand(commandObjects.ftSugGet(key, prefix, fuzzy, max)); - } - - @Override - public Response> ftSugGetWithScores(String key, String prefix) { - return appendCommand(commandObjects.ftSugGetWithScores(key, prefix)); - } - - @Override - public Response> ftSugGetWithScores(String key, String prefix, boolean fuzzy, int max) { - return appendCommand(commandObjects.ftSugGetWithScores(key, prefix, fuzzy, max)); - } - - @Override - public Response ftSugDel(String key, String string) { - return appendCommand(commandObjects.ftSugDel(key, string)); - } - - @Override - public Response ftSugLen(String key) { - return appendCommand(commandObjects.ftSugLen(key)); - } - // RediSearch commands - - // RedisJSON commands - @Override - public Response lcs(byte[] keyA, byte[] keyB, LCSParams params) { - return appendCommand(commandObjects.lcs(keyA, keyB, params)); - } - - @Override - public Response jsonSet(String key, Path2 path, Object object) { - return appendCommand(commandObjects.jsonSet(key, path, object)); - } - - @Override - public Response jsonSetWithEscape(String key, Path2 path, Object object) { - return appendCommand(commandObjects.jsonSetWithEscape(key, path, object)); - } - - @Override - public Response jsonSet(String key, Path path, Object object) { - return appendCommand(commandObjects.jsonSet(key, path, object)); - } - - @Override - public Response jsonSet(String key, Path2 path, Object object, JsonSetParams params) { - return appendCommand(commandObjects.jsonSet(key, path, object, params)); - } - - @Override - public Response jsonSetWithEscape(String key, Path2 path, Object object, JsonSetParams params) { - return appendCommand(commandObjects.jsonSetWithEscape(key, path, object, params)); - } - - @Override - public Response jsonSet(String key, Path path, Object object, JsonSetParams params) { - return appendCommand(commandObjects.jsonSet(key, path, object, params)); - } - - @Override - public Response jsonMerge(String key, Path2 path, Object object) { - return appendCommand(commandObjects.jsonMerge(key, path, object)); - } - - @Override - public Response jsonMerge(String key, Path path, Object object) { - return appendCommand(commandObjects.jsonMerge(key, path, object)); - } - - @Override - public Response jsonGet(String key) { - return appendCommand(commandObjects.jsonGet(key)); - } - - @Override - public Response jsonGet(String key, Class clazz) { - return appendCommand(commandObjects.jsonGet(key, clazz)); - } - - @Override - public Response jsonGet(String key, Path2... paths) { - return appendCommand(commandObjects.jsonGet(key, paths)); - } - - @Override - public Response jsonGet(String key, Path... paths) { - return appendCommand(commandObjects.jsonGet(key, paths)); - } - - @Override - public Response jsonGet(String key, Class clazz, Path... paths) { - return appendCommand(commandObjects.jsonGet(key, clazz, paths)); - } - - @Override - public Response> jsonMGet(Path2 path, String... keys) { - return appendCommand(commandObjects.jsonMGet(path, keys)); - } - - @Override - public Response> jsonMGet(Path path, Class clazz, String... keys) { - return appendCommand(commandObjects.jsonMGet(path, clazz, keys)); - } - - @Override - public Response jsonDel(String key) { - return appendCommand(commandObjects.jsonDel(key)); - } - - @Override - public Response jsonDel(String key, Path2 path) { - return appendCommand(commandObjects.jsonDel(key, path)); - } - - @Override - public Response jsonDel(String key, Path path) { - return appendCommand(commandObjects.jsonDel(key, path)); - } - - @Override - public Response jsonClear(String key) { - return appendCommand(commandObjects.jsonClear(key)); - } - - @Override - public Response jsonClear(String key, Path2 path) { - return appendCommand(commandObjects.jsonClear(key, path)); - } - - @Override - public Response jsonClear(String key, Path path) { - return appendCommand(commandObjects.jsonClear(key, path)); - } - - @Override - public Response> jsonToggle(String key, Path2 path) { - return appendCommand(commandObjects.jsonToggle(key, path)); - } - - @Override - public Response jsonToggle(String key, Path path) { - return appendCommand(commandObjects.jsonToggle(key, path)); - } - - @Override - public Response> jsonType(String key) { - return appendCommand(commandObjects.jsonType(key)); - } - - @Override - public Response>> jsonType(String key, Path2 path) { - return appendCommand(commandObjects.jsonType(key, path)); - } - - @Override - public Response> jsonType(String key, Path path) { - return appendCommand(commandObjects.jsonType(key, path)); - } - - @Override - public Response jsonStrAppend(String key, Object string) { - return appendCommand(commandObjects.jsonStrAppend(key, string)); - } - - @Override - public Response> jsonStrAppend(String key, Path2 path, Object string) { - return appendCommand(commandObjects.jsonStrAppend(key, path, string)); - } - - @Override - public Response jsonStrAppend(String key, Path path, Object string) { - return appendCommand(commandObjects.jsonStrAppend(key, path, string)); - } - - @Override - public Response jsonStrLen(String key) { - return appendCommand(commandObjects.jsonStrLen(key)); - } - - @Override - public Response> jsonStrLen(String key, Path2 path) { - return appendCommand(commandObjects.jsonStrLen(key, path)); - } - - @Override - public Response jsonStrLen(String key, Path path) { - return appendCommand(commandObjects.jsonStrLen(key, path)); - } - - @Override - public Response jsonNumIncrBy(String key, Path2 path, double value) { - return appendCommand(commandObjects.jsonNumIncrBy(key, path, value)); - } - - @Override - public Response jsonNumIncrBy(String key, Path path, double value) { - return appendCommand(commandObjects.jsonNumIncrBy(key, path, value)); - } - - @Override - public Response> jsonArrAppend(String key, Path2 path, Object... objects) { - return appendCommand(commandObjects.jsonArrAppend(key, path, objects)); - } - - @Override - public Response> jsonArrAppendWithEscape(String key, Path2 path, Object... objects) { - return appendCommand(commandObjects.jsonArrAppendWithEscape(key, path, objects)); - } - - @Override - public Response jsonArrAppend(String key, Path path, Object... objects) { - return appendCommand(commandObjects.jsonArrAppend(key, path, objects)); - } - - @Override - public Response> jsonArrIndex(String key, Path2 path, Object scalar) { - return appendCommand(commandObjects.jsonArrIndex(key, path, scalar)); - } - - @Override - public Response> jsonArrIndexWithEscape(String key, Path2 path, Object scalar) { - return appendCommand(commandObjects.jsonArrIndexWithEscape(key, path, scalar)); - } - - @Override - public Response jsonArrIndex(String key, Path path, Object scalar) { - return appendCommand(commandObjects.jsonArrIndex(key, path, scalar)); - } - - @Override - public Response> jsonArrInsert(String key, Path2 path, int index, Object... objects) { - return appendCommand(commandObjects.jsonArrInsert(key, path, index, objects)); - } - - @Override - public Response> jsonArrInsertWithEscape(String key, Path2 path, int index, Object... objects) { - return appendCommand(commandObjects.jsonArrInsertWithEscape(key, path, index, objects)); - } - - @Override - public Response jsonArrInsert(String key, Path path, int index, Object... pojos) { - return appendCommand(commandObjects.jsonArrInsert(key, path, index, pojos)); - } - - @Override - public Response jsonArrPop(String key) { - return appendCommand(commandObjects.jsonArrPop(key)); - } - - @Override - public Response jsonArrLen(String key, Path path) { - return appendCommand(commandObjects.jsonArrLen(key, path)); - } - - @Override - public Response> jsonArrTrim(String key, Path2 path, int start, int stop) { - return appendCommand(commandObjects.jsonArrTrim(key, path, start, stop)); - } - - @Override - public Response jsonArrTrim(String key, Path path, int start, int stop) { - return appendCommand(commandObjects.jsonArrTrim(key, path, start, stop)); - } - - @Override - public Response jsonArrPop(String key, Class clazz, Path path) { - return appendCommand(commandObjects.jsonArrPop(key, clazz, path)); - } - - @Override - public Response> jsonArrPop(String key, Path2 path, int index) { - return appendCommand(commandObjects.jsonArrPop(key, path, index)); - } - - @Override - public Response jsonArrPop(String key, Path path, int index) { - return appendCommand(commandObjects.jsonArrPop(key, path, index)); - } - - @Override - public Response jsonArrPop(String key, Class clazz, Path path, int index) { - return appendCommand(commandObjects.jsonArrPop(key, clazz, path, index)); - } - - @Override - public Response jsonArrLen(String key) { - return appendCommand(commandObjects.jsonArrLen(key)); - } - - @Override - public Response> jsonArrLen(String key, Path2 path) { - return appendCommand(commandObjects.jsonArrLen(key, path)); - } - - @Override - public Response jsonArrPop(String key, Class clazz) { - return appendCommand(commandObjects.jsonArrPop(key, clazz)); - } - - @Override - public Response> jsonArrPop(String key, Path2 path) { - return appendCommand(commandObjects.jsonArrPop(key, path)); - } - - @Override - public Response jsonArrPop(String key, Path path) { - return appendCommand(commandObjects.jsonArrPop(key, path)); - } - // RedisJSON commands - - // RedisTimeSeries commands - @Override - public Response tsCreate(String key) { - return appendCommand(commandObjects.tsCreate(key)); - } - - @Override - public Response tsCreate(String key, TSCreateParams createParams) { - return appendCommand(commandObjects.tsCreate(key, createParams)); - } - - @Override - public Response tsDel(String key, long fromTimestamp, long toTimestamp) { - return appendCommand(commandObjects.tsDel(key, fromTimestamp, toTimestamp)); - } - - @Override - public Response tsAlter(String key, TSAlterParams alterParams) { - return appendCommand(commandObjects.tsAlter(key, alterParams)); - } - - @Override - public Response tsAdd(String key, double value) { - return appendCommand(commandObjects.tsAdd(key, value)); - } - - @Override - public Response tsAdd(String key, long timestamp, double value) { - return appendCommand(commandObjects.tsAdd(key, timestamp, value)); - } - - @Override - public Response tsAdd(String key, long timestamp, double value, TSCreateParams createParams) { - return appendCommand(commandObjects.tsAdd(key, timestamp, value, createParams)); - } - - @Override - public Response> tsMAdd(Map.Entry... entries) { - return appendCommand(commandObjects.tsMAdd(entries)); - } - - @Override - public Response tsIncrBy(String key, double value) { - return appendCommand(commandObjects.tsIncrBy(key, value)); - } - - @Override - public Response tsIncrBy(String key, double value, long timestamp) { - return appendCommand(commandObjects.tsIncrBy(key, value, timestamp)); - } - - @Override - public Response tsDecrBy(String key, double value) { - return appendCommand(commandObjects.tsDecrBy(key, value)); - } - - @Override - public Response tsDecrBy(String key, double value, long timestamp) { - return appendCommand(commandObjects.tsDecrBy(key, value, timestamp)); - } - - @Override - public Response> tsRange(String key, long fromTimestamp, long toTimestamp) { - return appendCommand(commandObjects.tsRange(key, fromTimestamp, toTimestamp)); - } - - @Override - public Response> tsRange(String key, TSRangeParams rangeParams) { - return appendCommand(commandObjects.tsRange(key, rangeParams)); - } - - @Override - public Response> tsRevRange(String key, long fromTimestamp, long toTimestamp) { - return appendCommand(commandObjects.tsRevRange(key, fromTimestamp, toTimestamp)); - } - - @Override - public Response> tsRevRange(String key, TSRangeParams rangeParams) { - return appendCommand(commandObjects.tsRevRange(key, rangeParams)); - } - - @Override - public Response> tsMRange(long fromTimestamp, long toTimestamp, String... filters) { - return appendCommand(commandObjects.tsMRange(fromTimestamp, toTimestamp, filters)); - } - - @Override - public Response> tsMRange(TSMRangeParams multiRangeParams) { - return appendCommand(commandObjects.tsMRange(multiRangeParams)); - } - - @Override - public Response> tsMRevRange(long fromTimestamp, long toTimestamp, String... filters) { - return appendCommand(commandObjects.tsMRevRange(fromTimestamp, toTimestamp, filters)); - } - - @Override - public Response> tsMRevRange(TSMRangeParams multiRangeParams) { - return appendCommand(commandObjects.tsMRevRange(multiRangeParams)); - } - - @Override - public Response tsGet(String key) { - return appendCommand(commandObjects.tsGet(key)); - } - - @Override - public Response tsGet(String key, TSGetParams getParams) { - return appendCommand(commandObjects.tsGet(key, getParams)); - } - - @Override - public Response> tsMGet(TSMGetParams multiGetParams, String... filters) { - return appendCommand(commandObjects.tsMGet(multiGetParams, filters)); - } - - @Override - public Response tsCreateRule(String sourceKey, String destKey, AggregationType aggregationType, long timeBucket) { - return appendCommand(commandObjects.tsCreateRule(sourceKey, destKey, aggregationType, timeBucket)); - } - - @Override - public Response tsCreateRule(String sourceKey, String destKey, AggregationType aggregationType, long bucketDuration, long alignTimestamp) { - return appendCommand(commandObjects.tsCreateRule(sourceKey, destKey, aggregationType, bucketDuration, alignTimestamp)); - } - - @Override - public Response tsDeleteRule(String sourceKey, String destKey) { - return appendCommand(commandObjects.tsDeleteRule(sourceKey, destKey)); - } - - @Override - public Response> tsQueryIndex(String... filters) { - return appendCommand(commandObjects.tsQueryIndex(filters)); - } - // RedisTimeSeries commands - - // RedisBloom commands - @Override - public Response bfReserve(String key, double errorRate, long capacity) { - return appendCommand(commandObjects.bfReserve(key, errorRate, capacity)); - } - - @Override - public Response bfReserve(String key, double errorRate, long capacity, BFReserveParams reserveParams) { - return appendCommand(commandObjects.bfReserve(key, errorRate, capacity, reserveParams)); - } - - @Override - public Response bfAdd(String key, String item) { - return appendCommand(commandObjects.bfAdd(key, item)); - } - - @Override - public Response> bfMAdd(String key, String... items) { - return appendCommand(commandObjects.bfMAdd(key, items)); - } - - @Override - public Response> bfInsert(String key, String... items) { - return appendCommand(commandObjects.bfInsert(key, items)); - } - - @Override - public Response> bfInsert(String key, BFInsertParams insertParams, String... items) { - return appendCommand(commandObjects.bfInsert(key, insertParams, items)); - } - - @Override - public Response bfExists(String key, String item) { - return appendCommand(commandObjects.bfExists(key, item)); - } - - @Override - public Response> bfMExists(String key, String... items) { - return appendCommand(commandObjects.bfMExists(key, items)); - } - - @Override - public Response> bfScanDump(String key, long iterator) { - return appendCommand(commandObjects.bfScanDump(key, iterator)); - } - - @Override - public Response bfLoadChunk(String key, long iterator, byte[] data) { - return appendCommand(commandObjects.bfLoadChunk(key, iterator, data)); - } - - @Override - public Response bfCard(String key) { - return appendCommand(commandObjects.bfCard(key)); - } - - @Override - public Response> bfInfo(String key) { - return appendCommand(commandObjects.bfInfo(key)); - } - - @Override - public Response cfReserve(String key, long capacity) { - return appendCommand(commandObjects.cfReserve(key, capacity)); - } - - @Override - public Response cfReserve(String key, long capacity, CFReserveParams reserveParams) { - return appendCommand(commandObjects.cfReserve(key, capacity, reserveParams)); - } - - @Override - public Response cfAdd(String key, String item) { - return appendCommand(commandObjects.cfAdd(key, item)); - } - - @Override - public Response cfAddNx(String key, String item) { - return appendCommand(commandObjects.cfAddNx(key, item)); - } - - @Override - public Response> cfInsert(String key, String... items) { - return appendCommand(commandObjects.cfInsert(key, items)); - } - - @Override - public Response> cfInsert(String key, CFInsertParams insertParams, String... items) { - return appendCommand(commandObjects.cfInsert(key, insertParams, items)); - } - - @Override - public Response> cfInsertNx(String key, String... items) { - return appendCommand(commandObjects.cfInsertNx(key, items)); - } - - @Override - public Response> cfInsertNx(String key, CFInsertParams insertParams, String... items) { - return appendCommand(commandObjects.cfInsertNx(key, insertParams, items)); - } - - @Override - public Response cfExists(String key, String item) { - return appendCommand(commandObjects.cfExists(key, item)); - } - - @Override - public Response cfDel(String key, String item) { - return appendCommand(commandObjects.cfDel(key, item)); - } - - @Override - public Response cfCount(String key, String item) { - return appendCommand(commandObjects.cfCount(key, item)); - } - - @Override - public Response> cfScanDump(String key, long iterator) { - return appendCommand(commandObjects.cfScanDump(key, iterator)); - } - - @Override - public Response cfLoadChunk(String key, long iterator, byte[] data) { - return appendCommand(commandObjects.cfLoadChunk(key, iterator, data)); - } - - @Override - public Response> cfInfo(String key) { - return appendCommand(commandObjects.cfInfo(key)); - } - - @Override - public Response cmsInitByDim(String key, long width, long depth) { - return appendCommand(commandObjects.cmsInitByDim(key, width, depth)); - } - - @Override - public Response cmsInitByProb(String key, double error, double probability) { - return appendCommand(commandObjects.cmsInitByProb(key, error, probability)); - } - - @Override - public Response> cmsIncrBy(String key, Map itemIncrements) { - return appendCommand(commandObjects.cmsIncrBy(key, itemIncrements)); - } - - @Override - public Response> cmsQuery(String key, String... items) { - return appendCommand(commandObjects.cmsQuery(key, items)); - } - - @Override - public Response cmsMerge(String destKey, String... keys) { - return appendCommand(commandObjects.cmsMerge(destKey, keys)); - } - - @Override - public Response cmsMerge(String destKey, Map keysAndWeights) { - return appendCommand(commandObjects.cmsMerge(destKey, keysAndWeights)); - } - - @Override - public Response> cmsInfo(String key) { - return appendCommand(commandObjects.cmsInfo(key)); - } - - @Override - public Response topkReserve(String key, long topk) { - return appendCommand(commandObjects.topkReserve(key, topk)); - } - - @Override - public Response topkReserve(String key, long topk, long width, long depth, double decay) { - return appendCommand(commandObjects.topkReserve(key, topk, width, depth, decay)); - } - - @Override - public Response> topkAdd(String key, String... items) { - return appendCommand(commandObjects.topkAdd(key, items)); - } - - @Override - public Response> topkIncrBy(String key, Map itemIncrements) { - return appendCommand(commandObjects.topkIncrBy(key, itemIncrements)); - } - - @Override - public Response> topkQuery(String key, String... items) { - return appendCommand(commandObjects.topkQuery(key, items)); - } - - @Override - public Response> topkList(String key) { - return appendCommand(commandObjects.topkList(key)); - } - - @Override - public Response> topkListWithCount(String key) { - return appendCommand(commandObjects.topkListWithCount(key)); - } - - @Override - public Response> topkInfo(String key) { - return appendCommand(commandObjects.topkInfo(key)); - } - - @Override - public Response tdigestCreate(String key) { - return appendCommand(commandObjects.tdigestCreate(key)); - } - - @Override - public Response tdigestCreate(String key, int compression) { - return appendCommand(commandObjects.tdigestCreate(key, compression)); - } - - @Override - public Response tdigestReset(String key) { - return appendCommand(commandObjects.tdigestReset(key)); - } - - @Override - public Response tdigestMerge(String destinationKey, String... sourceKeys) { - return appendCommand(commandObjects.tdigestMerge(destinationKey, sourceKeys)); - } - - @Override - public Response tdigestMerge(TDigestMergeParams mergeParams, String destinationKey, String... sourceKeys) { - return appendCommand(commandObjects.tdigestMerge(mergeParams, destinationKey, sourceKeys)); - } - - @Override - public Response> tdigestInfo(String key) { - return appendCommand(commandObjects.tdigestInfo(key)); - } - - @Override - public Response tdigestAdd(String key, double... values) { - return appendCommand(commandObjects.tdigestAdd(key, values)); - } - - @Override - public Response> tdigestCDF(String key, double... values) { - return appendCommand(commandObjects.tdigestCDF(key, values)); - } - - @Override - public Response> tdigestQuantile(String key, double... quantiles) { - return appendCommand(commandObjects.tdigestQuantile(key, quantiles)); - } - - @Override - public Response tdigestMin(String key) { - return appendCommand(commandObjects.tdigestMin(key)); - } - - @Override - public Response tdigestMax(String key) { - return appendCommand(commandObjects.tdigestMax(key)); - } - - @Override - public Response tdigestTrimmedMean(String key, double lowCutQuantile, double highCutQuantile) { - return appendCommand(commandObjects.tdigestTrimmedMean(key, lowCutQuantile, highCutQuantile)); - } - - @Override - public Response> tdigestRank(String key, double... values) { - return appendCommand(commandObjects.tdigestRank(key, values)); - } - - @Override - public Response> tdigestRevRank(String key, double... values) { - return appendCommand(commandObjects.tdigestRevRank(key, values)); - } - - @Override - public Response> tdigestByRank(String key, long... ranks) { - return appendCommand(commandObjects.tdigestByRank(key, ranks)); - } - - @Override - public Response> tdigestByRevRank(String key, long... ranks) { - return appendCommand(commandObjects.tdigestByRevRank(key, ranks)); - } - // RedisBloom commands - - // RedisGraph commands - @Override - public Response graphQuery(String name, String query) { - return appendCommand(graphCommandObjects.graphQuery(name, query)); - } - - @Override - public Response graphReadonlyQuery(String name, String query) { - return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query)); - } - - @Override - public Response graphQuery(String name, String query, long timeout) { - return appendCommand(graphCommandObjects.graphQuery(name, query, timeout)); - } - - @Override - public Response graphReadonlyQuery(String name, String query, long timeout) { - return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query, timeout)); - } - - @Override - public Response graphQuery(String name, String query, Map params) { - return appendCommand(graphCommandObjects.graphQuery(name, query, params)); - } - - @Override - public Response graphReadonlyQuery(String name, String query, Map params) { - return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query, params)); - } - - @Override - public Response graphQuery(String name, String query, Map params, long timeout) { - return appendCommand(graphCommandObjects.graphQuery(name, query, params, timeout)); - } - - @Override - public Response graphReadonlyQuery(String name, String query, Map params, long timeout) { - return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query, params, timeout)); - } - - @Override - public Response graphDelete(String name) { - return appendCommand(graphCommandObjects.graphDelete(name)); - } - - @Override - public Response> graphProfile(String graphName, String query) { - return appendCommand(commandObjects.graphProfile(graphName, query)); - } - // RedisGraph commands - - public Response publish(String channel, String message) { - return appendCommand(commandObjects.publish(channel, message)); - } - - public Response publish(byte[] channel, byte[] message) { - return appendCommand(commandObjects.publish(channel, message)); - } - - public Response sendCommand(ProtocolCommand cmd, String... args) { - return sendCommand(new CommandArguments(cmd).addObjects((Object[]) args)); - } - - public Response sendCommand(ProtocolCommand cmd, byte[]... args) { - return sendCommand(new CommandArguments(cmd).addObjects((Object[]) args)); - } - - public Response sendCommand(CommandArguments args) { - return executeCommand(new CommandObject<>(args, BuilderFactory.RAW_OBJECT)); - } - - public Response executeCommand(CommandObject command) { - return appendCommand(command); - } - - public void setJsonObjectMapper(JsonObjectMapper jsonObjectMapper) { - this.commandObjects.setJsonObjectMapper(jsonObjectMapper); +/** + * @deprecated Use {@link AbstractPipeline}. + */ +@Deprecated +public abstract class PipelineBase extends AbstractPipeline { + + protected PipelineBase(CommandObjects commandObjects) { + super(commandObjects); } } diff --git a/src/main/java/redis/clients/jedis/PipeliningBase.java b/src/main/java/redis/clients/jedis/PipeliningBase.java new file mode 100644 index 0000000000..bf6711b632 --- /dev/null +++ b/src/main/java/redis/clients/jedis/PipeliningBase.java @@ -0,0 +1,4252 @@ +package redis.clients.jedis; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.json.JSONArray; + +import redis.clients.jedis.args.*; +import redis.clients.jedis.bloom.*; +import redis.clients.jedis.commands.PipelineBinaryCommands; +import redis.clients.jedis.commands.PipelineCommands; +import redis.clients.jedis.commands.ProtocolCommand; +import redis.clients.jedis.commands.RedisModulePipelineCommands; +import redis.clients.jedis.graph.GraphCommandObjects; +import redis.clients.jedis.graph.ResultSet; +import redis.clients.jedis.json.JsonSetParams; +import redis.clients.jedis.json.Path; +import redis.clients.jedis.json.Path2; +import redis.clients.jedis.json.JsonObjectMapper; +import redis.clients.jedis.params.*; +import redis.clients.jedis.resps.*; +import redis.clients.jedis.search.*; +import redis.clients.jedis.search.aggr.AggregationBuilder; +import redis.clients.jedis.search.aggr.AggregationResult; +import redis.clients.jedis.search.schemafields.SchemaField; +import redis.clients.jedis.timeseries.*; +import redis.clients.jedis.util.KeyValue; + +public abstract class PipeliningBase + implements PipelineCommands, PipelineBinaryCommands, RedisModulePipelineCommands { + + protected final CommandObjects commandObjects; + private GraphCommandObjects graphCommandObjects; + + protected PipeliningBase(CommandObjects commandObjects) { + this.commandObjects = commandObjects; + } + + /** + * Sub-classes must call this method, if graph commands are going to be used. + */ + protected final void setGraphCommands(GraphCommandObjects graphCommandObjects) { + this.graphCommandObjects = graphCommandObjects; + } + + protected abstract Response appendCommand(CommandObject commandObject); + + @Override + public Response exists(String key) { + return appendCommand(commandObjects.exists(key)); + } + + @Override + public Response exists(String... keys) { + return appendCommand(commandObjects.exists(keys)); + } + + @Override + public Response persist(String key) { + return appendCommand(commandObjects.persist(key)); + } + + @Override + public Response type(String key) { + return appendCommand(commandObjects.type(key)); + } + + @Override + public Response dump(String key) { + return appendCommand(commandObjects.dump(key)); + } + + @Override + public Response restore(String key, long ttl, byte[] serializedValue) { + return appendCommand(commandObjects.restore(key, ttl, serializedValue)); + } + + @Override + public Response restore(String key, long ttl, byte[] serializedValue, RestoreParams params) { + return appendCommand(commandObjects.restore(key, ttl, serializedValue, params)); + } + + @Override + public Response expire(String key, long seconds) { + return appendCommand(commandObjects.expire(key, seconds)); + } + + @Override + public Response expire(String key, long seconds, ExpiryOption expiryOption) { + return appendCommand(commandObjects.expire(key, seconds, expiryOption)); + } + + @Override + public Response pexpire(String key, long milliseconds) { + return appendCommand(commandObjects.pexpire(key, milliseconds)); + } + + @Override + public Response pexpire(String key, long milliseconds, ExpiryOption expiryOption) { + return appendCommand(commandObjects.pexpire(key, milliseconds, expiryOption)); + } + + @Override + public Response expireTime(String key) { + return appendCommand(commandObjects.expireTime(key)); + } + + @Override + public Response pexpireTime(String key) { + return appendCommand(commandObjects.pexpireTime(key)); + } + + @Override + public Response expireAt(String key, long unixTime) { + return appendCommand(commandObjects.expireAt(key, unixTime)); + } + + @Override + public Response expireAt(String key, long unixTime, ExpiryOption expiryOption) { + return appendCommand(commandObjects.expireAt(key, unixTime, expiryOption)); + } + + @Override + public Response pexpireAt(String key, long millisecondsTimestamp) { + return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp)); + } + + @Override + public Response pexpireAt(String key, long millisecondsTimestamp, ExpiryOption expiryOption) { + return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp, expiryOption)); + } + + @Override + public Response ttl(String key) { + return appendCommand(commandObjects.ttl(key)); + } + + @Override + public Response pttl(String key) { + return appendCommand(commandObjects.pttl(key)); + } + + @Override + public Response touch(String key) { + return appendCommand(commandObjects.touch(key)); + } + + @Override + public Response touch(String... keys) { + return appendCommand(commandObjects.touch(keys)); + } + + @Override + public Response> sort(String key) { + return appendCommand(commandObjects.sort(key)); + } + + @Override + public Response sort(String key, String dstKey) { + return appendCommand(commandObjects.sort(key, dstKey)); + } + + @Override + public Response> sort(String key, SortingParams sortingParams) { + return appendCommand(commandObjects.sort(key, sortingParams)); + } + + @Override + public Response sort(String key, SortingParams sortingParams, String dstKey) { + return appendCommand(commandObjects.sort(key, sortingParams, dstKey)); + } + + @Override + public Response> sortReadonly(String key, SortingParams sortingParams) { + return appendCommand(commandObjects.sortReadonly(key, sortingParams)); + } + + @Override + public Response del(String key) { + return appendCommand(commandObjects.del(key)); + } + + @Override + public Response del(String... keys) { + return appendCommand(commandObjects.del(keys)); + } + + @Override + public Response unlink(String key) { + return appendCommand(commandObjects.unlink(key)); + } + + @Override + public Response unlink(String... keys) { + return appendCommand(commandObjects.unlink(keys)); + } + + @Override + public Response copy(String srcKey, String dstKey, boolean replace) { + return appendCommand(commandObjects.copy(srcKey, dstKey, replace)); + } + + @Override + public Response rename(String oldkey, String newkey) { + return appendCommand(commandObjects.rename(oldkey, newkey)); + } + + @Override + public Response renamenx(String oldkey, String newkey) { + return appendCommand(commandObjects.renamenx(oldkey, newkey)); + } + + @Override + public Response memoryUsage(String key) { + return appendCommand(commandObjects.memoryUsage(key)); + } + + @Override + public Response memoryUsage(String key, int samples) { + return appendCommand(commandObjects.memoryUsage(key, samples)); + } + + @Override + public Response objectRefcount(String key) { + return appendCommand(commandObjects.objectRefcount(key)); + } + + @Override + public Response objectEncoding(String key) { + return appendCommand(commandObjects.objectEncoding(key)); + } + + @Override + public Response objectIdletime(String key) { + return appendCommand(commandObjects.objectIdletime(key)); + } + + @Override + public Response objectFreq(String key) { + return appendCommand(commandObjects.objectFreq(key)); + } + + @Override + public Response migrate(String host, int port, String key, int timeout) { + return appendCommand(commandObjects.migrate(host, port, key, timeout)); + } + + @Override + public Response migrate(String host, int port, int timeout, MigrateParams params, String... keys) { + return appendCommand(commandObjects.migrate(host, port, timeout, params, keys)); + } + + @Override + public Response> keys(String pattern) { + return appendCommand(commandObjects.keys(pattern)); + } + + @Override + public Response> scan(String cursor) { + return appendCommand(commandObjects.scan(cursor)); + } + + @Override + public Response> scan(String cursor, ScanParams params) { + return appendCommand(commandObjects.scan(cursor, params)); + } + + @Override + public Response> scan(String cursor, ScanParams params, String type) { + return appendCommand(commandObjects.scan(cursor, params, type)); + } + + @Override + public Response randomKey() { + return appendCommand(commandObjects.randomKey()); + } + + @Override + public Response get(String key) { + return appendCommand(commandObjects.get(key)); + } + + @Override + public Response setGet(String key, String value, SetParams params) { + return appendCommand(commandObjects.setGet(key, value, params)); + } + + @Override + public Response getDel(String key) { + return appendCommand(commandObjects.getDel(key)); + } + + @Override + public Response getEx(String key, GetExParams params) { + return appendCommand(commandObjects.getEx(key, params)); + } + + @Override + public Response setbit(String key, long offset, boolean value) { + return appendCommand(commandObjects.setbit(key, offset, value)); + } + + @Override + public Response getbit(String key, long offset) { + return appendCommand(commandObjects.getbit(key, offset)); + } + + @Override + public Response setrange(String key, long offset, String value) { + return appendCommand(commandObjects.setrange(key, offset, value)); + } + + @Override + public Response getrange(String key, long startOffset, long endOffset) { + return appendCommand(commandObjects.getrange(key, startOffset, endOffset)); + } + + @Override + public Response getSet(String key, String value) { + return appendCommand(commandObjects.getSet(key, value)); + } + + @Override + public Response setnx(String key, String value) { + return appendCommand(commandObjects.setnx(key, value)); + } + + @Override + public Response setex(String key, long seconds, String value) { + return appendCommand(commandObjects.setex(key, seconds, value)); + } + + @Override + public Response psetex(String key, long milliseconds, String value) { + return appendCommand(commandObjects.psetex(key, milliseconds, value)); + } + + @Override + public Response> mget(String... keys) { + return appendCommand(commandObjects.mget(keys)); + } + + @Override + public Response mset(String... keysvalues) { + return appendCommand(commandObjects.mset(keysvalues)); + } + + @Override + public Response msetnx(String... keysvalues) { + return appendCommand(commandObjects.msetnx(keysvalues)); + } + + @Override + public Response incr(String key) { + return appendCommand(commandObjects.incr(key)); + } + + @Override + public Response incrBy(String key, long increment) { + return appendCommand(commandObjects.incrBy(key, increment)); + } + + @Override + public Response incrByFloat(String key, double increment) { + return appendCommand(commandObjects.incrByFloat(key, increment)); + } + + @Override + public Response decr(String key) { + return appendCommand(commandObjects.decr(key)); + } + + @Override + public Response decrBy(String key, long decrement) { + return appendCommand(commandObjects.decrBy(key, decrement)); + } + + @Override + public Response append(String key, String value) { + return appendCommand(commandObjects.append(key, value)); + } + + @Override + public Response substr(String key, int start, int end) { + return appendCommand(commandObjects.substr(key, start, end)); + } + + @Override + public Response strlen(String key) { + return appendCommand(commandObjects.strlen(key)); + } + + @Override + public Response bitcount(String key) { + return appendCommand(commandObjects.bitcount(key)); + } + + @Override + public Response bitcount(String key, long start, long end) { + return appendCommand(commandObjects.bitcount(key, start, end)); + } + + @Override + public Response bitcount(String key, long start, long end, BitCountOption option) { + return appendCommand(commandObjects.bitcount(key, start, end, option)); + } + + @Override + public Response bitpos(String key, boolean value) { + return appendCommand(commandObjects.bitpos(key, value)); + } + + @Override + public Response bitpos(String key, boolean value, BitPosParams params) { + return appendCommand(commandObjects.bitpos(key, value, params)); + } + + @Override + public Response> bitfield(String key, String... arguments) { + return appendCommand(commandObjects.bitfield(key, arguments)); + } + + @Override + public Response> bitfieldReadonly(String key, String... arguments) { + return appendCommand(commandObjects.bitfieldReadonly(key, arguments)); + } + + @Override + public Response bitop(BitOP op, String destKey, String... srcKeys) { + return appendCommand(commandObjects.bitop(op, destKey, srcKeys)); + } + + @Override + public Response lcs(String keyA, String keyB, LCSParams params) { + return appendCommand(commandObjects.lcs(keyA, keyB, params)); + } + + @Override + public Response set(String key, String value) { + return appendCommand(commandObjects.set(key, value)); + } + + @Override + public Response set(String key, String value, SetParams params) { + return appendCommand(commandObjects.set(key, value, params)); + } + + @Override + public Response rpush(String key, String... string) { + return appendCommand(commandObjects.rpush(key, string)); + + } + + @Override + public Response lpush(String key, String... string) { + return appendCommand(commandObjects.lpush(key, string)); + } + + @Override + public Response llen(String key) { + return appendCommand(commandObjects.llen(key)); + } + + @Override + public Response> lrange(String key, long start, long stop) { + return appendCommand(commandObjects.lrange(key, start, stop)); + } + + @Override + public Response ltrim(String key, long start, long stop) { + return appendCommand(commandObjects.ltrim(key, start, stop)); + } + + @Override + public Response lindex(String key, long index) { + return appendCommand(commandObjects.lindex(key, index)); + } + + @Override + public Response lset(String key, long index, String value) { + return appendCommand(commandObjects.lset(key, index, value)); + } + + @Override + public Response lrem(String key, long count, String value) { + return appendCommand(commandObjects.lrem(key, count, value)); + } + + @Override + public Response lpop(String key) { + return appendCommand(commandObjects.lpop(key)); + } + + @Override + public Response> lpop(String key, int count) { + return appendCommand(commandObjects.lpop(key, count)); + } + + @Override + public Response lpos(String key, String element) { + return appendCommand(commandObjects.lpos(key, element)); + } + + @Override + public Response lpos(String key, String element, LPosParams params) { + return appendCommand(commandObjects.lpos(key, element, params)); + } + + @Override + public Response> lpos(String key, String element, LPosParams params, long count) { + return appendCommand(commandObjects.lpos(key, element, params, count)); + } + + @Override + public Response rpop(String key) { + return appendCommand(commandObjects.rpop(key)); + } + + @Override + public Response> rpop(String key, int count) { + return appendCommand(commandObjects.rpop(key, count)); + } + + @Override + public Response linsert(String key, ListPosition where, String pivot, String value) { + return appendCommand(commandObjects.linsert(key, where, pivot, value)); + } + + @Override + public Response lpushx(String key, String... strings) { + return appendCommand(commandObjects.lpushx(key, strings)); + } + + @Override + public Response rpushx(String key, String... strings) { + return appendCommand(commandObjects.rpushx(key, strings)); + } + + @Override + public Response> blpop(int timeout, String key) { + return appendCommand(commandObjects.blpop(timeout, key)); + } + + @Override + public Response> blpop(double timeout, String key) { + return appendCommand(commandObjects.blpop(timeout, key)); + } + + @Override + public Response> brpop(int timeout, String key) { + return appendCommand(commandObjects.brpop(timeout, key)); + } + + @Override + public Response> brpop(double timeout, String key) { + return appendCommand(commandObjects.brpop(timeout, key)); + } + + @Override + public Response> blpop(int timeout, String... keys) { + return appendCommand(commandObjects.blpop(timeout, keys)); + } + + @Override + public Response> blpop(double timeout, String... keys) { + return appendCommand(commandObjects.blpop(timeout, keys)); + } + + @Override + public Response> brpop(int timeout, String... keys) { + return appendCommand(commandObjects.brpop(timeout, keys)); + } + + @Override + public Response> brpop(double timeout, String... keys) { + return appendCommand(commandObjects.brpop(timeout, keys)); + } + + @Override + public Response rpoplpush(String srcKey, String dstKey) { + return appendCommand(commandObjects.rpoplpush(srcKey, dstKey)); + } + + @Override + public Response brpoplpush(String source, String destination, int timeout) { + return appendCommand(commandObjects.brpoplpush(source, destination, timeout)); + } + + @Override + public Response lmove(String srcKey, String dstKey, ListDirection from, ListDirection to) { + return appendCommand(commandObjects.lmove(srcKey, dstKey, from, to)); + } + + @Override + public Response blmove(String srcKey, String dstKey, ListDirection from, ListDirection to, double timeout) { + return appendCommand(commandObjects.blmove(srcKey, dstKey, from, to, timeout)); + } + + @Override + public Response>> lmpop(ListDirection direction, String... keys) { + return appendCommand(commandObjects.lmpop(direction, keys)); + } + + @Override + public Response>> lmpop(ListDirection direction, int count, String... keys) { + return appendCommand(commandObjects.lmpop(direction, count, keys)); + } + + @Override + public Response>> blmpop(double timeout, ListDirection direction, String... keys) { + return appendCommand(commandObjects.blmpop(timeout, direction, keys)); + } + + @Override + public Response>> blmpop(double timeout, ListDirection direction, int count, String... keys) { + return appendCommand(commandObjects.blmpop(timeout, direction, count, keys)); + } + + @Override + public Response hset(String key, String field, String value) { + return appendCommand(commandObjects.hset(key, field, value)); + } + + @Override + public Response hset(String key, Map hash) { + return appendCommand(commandObjects.hset(key, hash)); + } + + @Override + public Response hget(String key, String field) { + return appendCommand(commandObjects.hget(key, field)); + } + + @Override + public Response hsetnx(String key, String field, String value) { + return appendCommand(commandObjects.hsetnx(key, field, value)); + } + + @Override + public Response hmset(String key, Map hash) { + return appendCommand(commandObjects.hmset(key, hash)); + } + + @Override + public Response> hmget(String key, String... fields) { + return appendCommand(commandObjects.hmget(key, fields)); + } + + @Override + public Response hincrBy(String key, String field, long value) { + return appendCommand(commandObjects.hincrBy(key, field, value)); + } + + @Override + public Response hincrByFloat(String key, String field, double value) { + return appendCommand(commandObjects.hincrByFloat(key, field, value)); + } + + @Override + public Response hexists(String key, String field) { + return appendCommand(commandObjects.hexists(key, field)); + } + + @Override + public Response hdel(String key, String... field) { + return appendCommand(commandObjects.hdel(key, field)); + } + + @Override + public Response hlen(String key) { + return appendCommand(commandObjects.hlen(key)); + } + + @Override + public Response> hkeys(String key) { + return appendCommand(commandObjects.hkeys(key)); + } + + @Override + public Response> hvals(String key) { + return appendCommand(commandObjects.hvals(key)); + } + + @Override + public Response> hgetAll(String key) { + return appendCommand(commandObjects.hgetAll(key)); + } + + @Override + public Response hrandfield(String key) { + return appendCommand(commandObjects.hrandfield(key)); + } + + @Override + public Response> hrandfield(String key, long count) { + return appendCommand(commandObjects.hrandfield(key, count)); + } + + @Override + public Response>> hrandfieldWithValues(String key, long count) { + return appendCommand(commandObjects.hrandfieldWithValues(key, count)); + } + + @Override + public Response>> hscan(String key, String cursor, ScanParams params) { + return appendCommand(commandObjects.hscan(key, cursor, params)); + } + + @Override + public Response> hscanNoValues(String key, String cursor, ScanParams params) { + return appendCommand(commandObjects.hscanNoValues(key, cursor, params)); + } + + @Override + public Response hstrlen(String key, String field) { + return appendCommand(commandObjects.hstrlen(key, field)); + } + + @Override + public Response sadd(String key, String... members) { + return appendCommand(commandObjects.sadd(key, members)); + } + + @Override + public Response> smembers(String key) { + return appendCommand(commandObjects.smembers(key)); + } + + @Override + public Response srem(String key, String... members) { + return appendCommand(commandObjects.srem(key, members)); + } + + @Override + public Response spop(String key) { + return appendCommand(commandObjects.spop(key)); + } + + @Override + public Response> spop(String key, long count) { + return appendCommand(commandObjects.spop(key, count)); + } + + @Override + public Response scard(String key) { + return appendCommand(commandObjects.scard(key)); + } + + @Override + public Response sismember(String key, String member) { + return appendCommand(commandObjects.sismember(key, member)); + } + + @Override + public Response> smismember(String key, String... members) { + return appendCommand(commandObjects.smismember(key, members)); + } + + @Override + public Response srandmember(String key) { + return appendCommand(commandObjects.srandmember(key)); + } + + @Override + public Response> srandmember(String key, int count) { + return appendCommand(commandObjects.srandmember(key, count)); + } + + @Override + public Response> sscan(String key, String cursor, ScanParams params) { + return appendCommand(commandObjects.sscan(key, cursor, params)); + } + + @Override + public Response> sdiff(String... keys) { + return appendCommand(commandObjects.sdiff(keys)); + } + + @Override + public Response sdiffStore(String dstKey, String... keys) { + return appendCommand(commandObjects.sdiffstore(dstKey, keys)); + } + + @Override + public Response> sinter(String... keys) { + return appendCommand(commandObjects.sinter(keys)); + } + + @Override + public Response sinterstore(String dstKey, String... keys) { + return appendCommand(commandObjects.sinterstore(dstKey, keys)); + } + + @Override + public Response sintercard(String... keys) { + return appendCommand(commandObjects.sintercard(keys)); + } + + @Override + public Response sintercard(int limit, String... keys) { + return appendCommand(commandObjects.sintercard(limit, keys)); + } + + @Override + public Response> sunion(String... keys) { + return appendCommand(commandObjects.sunion(keys)); + } + + @Override + public Response sunionstore(String dstKey, String... keys) { + return appendCommand(commandObjects.sunionstore(dstKey, keys)); + } + + @Override + public Response smove(String srcKey, String dstKey, String member) { + return appendCommand(commandObjects.smove(srcKey, dstKey, member)); + } + + @Override + public Response zadd(String key, double score, String member) { + return appendCommand(commandObjects.zadd(key, score, member)); + } + + @Override + public Response zadd(String key, double score, String member, ZAddParams params) { + return appendCommand(commandObjects.zadd(key, score, member, params)); + } + + @Override + public Response zadd(String key, Map scoreMembers) { + return appendCommand(commandObjects.zadd(key, scoreMembers)); + } + + @Override + public Response zadd(String key, Map scoreMembers, ZAddParams params) { + return appendCommand(commandObjects.zadd(key, scoreMembers, params)); + } + + @Override + public Response zaddIncr(String key, double score, String member, ZAddParams params) { + return appendCommand(commandObjects.zaddIncr(key, score, member, params)); + } + + @Override + public Response zrem(String key, String... members) { + return appendCommand(commandObjects.zrem(key, members)); + } + + @Override + public Response zincrby(String key, double increment, String member) { + return appendCommand(commandObjects.zincrby(key, increment, member)); + } + + @Override + public Response zincrby(String key, double increment, String member, ZIncrByParams params) { + return appendCommand(commandObjects.zincrby(key, increment, member, params)); + } + + @Override + public Response zrank(String key, String member) { + return appendCommand(commandObjects.zrank(key, member)); + } + + @Override + public Response zrevrank(String key, String member) { + return appendCommand(commandObjects.zrevrank(key, member)); + } + + @Override + public Response> zrankWithScore(String key, String member) { + return appendCommand(commandObjects.zrankWithScore(key, member)); + } + + @Override + public Response> zrevrankWithScore(String key, String member) { + return appendCommand(commandObjects.zrevrankWithScore(key, member)); + } + + @Override + public Response> zrange(String key, long start, long stop) { + return appendCommand(commandObjects.zrange(key, start, stop)); + } + + @Override + public Response> zrevrange(String key, long start, long stop) { + return appendCommand(commandObjects.zrevrange(key, start, stop)); + } + + @Override + public Response> zrangeWithScores(String key, long start, long stop) { + return appendCommand(commandObjects.zrangeWithScores(key, start, stop)); + } + + @Override + public Response> zrevrangeWithScores(String key, long start, long stop) { + return appendCommand(commandObjects.zrevrangeWithScores(key, start, stop)); + } + + @Override + public Response zrandmember(String key) { + return appendCommand(commandObjects.zrandmember(key)); + } + + @Override + public Response> zrandmember(String key, long count) { + return appendCommand(commandObjects.zrandmember(key, count)); + } + + @Override + public Response> zrandmemberWithScores(String key, long count) { + return appendCommand(commandObjects.zrandmemberWithScores(key, count)); + } + + @Override + public Response zcard(String key) { + return appendCommand(commandObjects.zcard(key)); + } + + @Override + public Response zscore(String key, String member) { + return appendCommand(commandObjects.zscore(key, member)); + } + + @Override + public Response> zmscore(String key, String... members) { + return appendCommand(commandObjects.zmscore(key, members)); + } + + @Override + public Response zpopmax(String key) { + return appendCommand(commandObjects.zpopmax(key)); + } + + @Override + public Response> zpopmax(String key, int count) { + return appendCommand(commandObjects.zpopmax(key, count)); + } + + @Override + public Response zpopmin(String key) { + return appendCommand(commandObjects.zpopmin(key)); + } + + @Override + public Response> zpopmin(String key, int count) { + return appendCommand(commandObjects.zpopmin(key, count)); + } + + @Override + public Response zcount(String key, double min, double max) { + return appendCommand(commandObjects.zcount(key, min, max)); + } + + @Override + public Response zcount(String key, String min, String max) { + return appendCommand(commandObjects.zcount(key, min, max)); + } + + @Override + public Response> zrangeByScore(String key, double min, double max) { + return appendCommand(commandObjects.zrangeByScore(key, min, max)); + } + + @Override + public Response> zrangeByScore(String key, String min, String max) { + return appendCommand(commandObjects.zrangeByScore(key, min, max)); + } + + @Override + public Response> zrevrangeByScore(String key, double max, double min) { + return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); + } + + @Override + public Response> zrangeByScore(String key, double min, double max, int offset, int count) { + return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByScore(String key, String max, String min) { + return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); + } + + @Override + public Response> zrangeByScore(String key, String min, String max, int offset, int count) { + return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByScore(String key, double max, double min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); + } + + @Override + public Response> zrangeByScoreWithScores(String key, double min, double max) { + return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); + } + + @Override + public Response> zrevrangeByScoreWithScores(String key, double max, double min) { + return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); + } + + @Override + public Response> zrangeByScoreWithScores(String key, double min, double max, int offset, int count) { + return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByScore(String key, String max, String min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); + } + + @Override + public Response> zrangeByScoreWithScores(String key, String min, String max) { + return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); + } + + @Override + public Response> zrevrangeByScoreWithScores(String key, String max, String min) { + return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); + } + + @Override + public Response> zrangeByScoreWithScores(String key, String min, String max, int offset, int count) { + return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByScoreWithScores(String key, double max, double min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); + } + + @Override + public Response> zrevrangeByScoreWithScores(String key, String max, String min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); + } + + @Override + public Response> zrange(String key, ZRangeParams zRangeParams) { + return appendCommand(commandObjects.zrange(key, zRangeParams)); + } + + @Override + public Response> zrangeWithScores(String key, ZRangeParams zRangeParams) { + return appendCommand(commandObjects.zrangeWithScores(key, zRangeParams)); + } + + @Override + public Response zrangestore(String dest, String src, ZRangeParams zRangeParams) { + return appendCommand(commandObjects.zrangestore(dest, src, zRangeParams)); + } + + @Override + public Response zremrangeByRank(String key, long start, long stop) { + return appendCommand(commandObjects.zremrangeByRank(key, start, stop)); + } + + @Override + public Response zremrangeByScore(String key, double min, double max) { + return appendCommand(commandObjects.zremrangeByScore(key, min, max)); + } + + @Override + public Response zremrangeByScore(String key, String min, String max) { + return appendCommand(commandObjects.zremrangeByScore(key, min, max)); + } + + @Override + public Response zlexcount(String key, String min, String max) { + return appendCommand(commandObjects.zlexcount(key, min, max)); + } + + @Override + public Response> zrangeByLex(String key, String min, String max) { + return appendCommand(commandObjects.zrangeByLex(key, min, max)); + } + + @Override + public Response> zrangeByLex(String key, String min, String max, int offset, int count) { + return appendCommand(commandObjects.zrangeByLex(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByLex(String key, String max, String min) { + return appendCommand(commandObjects.zrevrangeByLex(key, max, min)); + } + + @Override + public Response> zrevrangeByLex(String key, String max, String min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByLex(key, max, min, offset, count)); + } + + @Override + public Response zremrangeByLex(String key, String min, String max) { + return appendCommand(commandObjects.zremrangeByLex(key, min, max)); + } + + @Override + public Response> zscan(String key, String cursor, ScanParams params) { + return appendCommand(commandObjects.zscan(key, cursor, params)); + } + + @Override + public Response> bzpopmax(double timeout, String... keys) { + return appendCommand(commandObjects.bzpopmax(timeout, keys)); + } + + @Override + public Response> bzpopmin(double timeout, String... keys) { + return appendCommand(commandObjects.bzpopmin(timeout, keys)); + } + + @Override + public Response>> zmpop(SortedSetOption option, String... keys) { + return appendCommand(commandObjects.zmpop(option, keys)); + } + + @Override + public Response>> zmpop(SortedSetOption option, int count, String... keys) { + return appendCommand(commandObjects.zmpop(option, count, keys)); + } + + @Override + public Response>> bzmpop(double timeout, SortedSetOption option, String... keys) { + return appendCommand(commandObjects.bzmpop(timeout, option, keys)); + } + + @Override + public Response>> bzmpop(double timeout, SortedSetOption option, int count, String... keys) { + return appendCommand(commandObjects.bzmpop(timeout, option, count, keys)); + } + + @Override + public Response> zdiff(String... keys) { + return appendCommand(commandObjects.zdiff(keys)); + } + + @Override + public Response> zdiffWithScores(String... keys) { + return appendCommand(commandObjects.zdiffWithScores(keys)); + } + + @Override + @Deprecated + public Response zdiffStore(String dstKey, String... keys) { + return appendCommand(commandObjects.zdiffStore(dstKey, keys)); + } + + @Override + public Response zdiffstore(String dstKey, String... keys) { + return appendCommand(commandObjects.zdiffstore(dstKey, keys)); + } + + @Override + public Response zinterstore(String dstKey, String... sets) { + return appendCommand(commandObjects.zinterstore(dstKey, sets)); + } + + @Override + public Response zinterstore(String dstKey, ZParams params, String... sets) { + return appendCommand(commandObjects.zinterstore(dstKey, params, sets)); + } + + @Override + public Response> zinter(ZParams params, String... keys) { + return appendCommand(commandObjects.zinter(params, keys)); + } + + @Override + public Response> zinterWithScores(ZParams params, String... keys) { + return appendCommand(commandObjects.zinterWithScores(params, keys)); + } + + @Override + public Response zintercard(String... keys) { + return appendCommand(commandObjects.zintercard(keys)); + } + + @Override + public Response zintercard(long limit, String... keys) { + return appendCommand(commandObjects.zintercard(limit, keys)); + } + + @Override + public Response> zunion(ZParams params, String... keys) { + return appendCommand(commandObjects.zunion(params, keys)); + } + + @Override + public Response> zunionWithScores(ZParams params, String... keys) { + return appendCommand(commandObjects.zunionWithScores(params, keys)); + } + + @Override + public Response zunionstore(String dstKey, String... sets) { + return appendCommand(commandObjects.zunionstore(dstKey, sets)); + } + + @Override + public Response zunionstore(String dstKey, ZParams params, String... sets) { + return appendCommand(commandObjects.zunionstore(dstKey, params, sets)); + } + + @Override + public Response geoadd(String key, double longitude, double latitude, String member) { + return appendCommand(commandObjects.geoadd(key, longitude, latitude, member)); + } + + @Override + public Response geoadd(String key, Map memberCoordinateMap) { + return appendCommand(commandObjects.geoadd(key, memberCoordinateMap)); + } + + @Override + public Response geoadd(String key, GeoAddParams params, Map memberCoordinateMap) { + return appendCommand(commandObjects.geoadd(key, params, memberCoordinateMap)); + } + + @Override + public Response geodist(String key, String member1, String member2) { + return appendCommand(commandObjects.geodist(key, member1, member2)); + } + + @Override + public Response geodist(String key, String member1, String member2, GeoUnit unit) { + return appendCommand(commandObjects.geodist(key, member1, member2, unit)); + } + + @Override + public Response> geohash(String key, String... members) { + return appendCommand(commandObjects.geohash(key, members)); + } + + @Override + public Response> geopos(String key, String... members) { + return appendCommand(commandObjects.geopos(key, members)); + } + + @Override + public Response> georadius(String key, double longitude, double latitude, double radius, GeoUnit unit) { + return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit)); + } + + @Override + public Response> georadiusReadonly(String key, double longitude, double latitude, double radius, GeoUnit unit) { + return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit)); + } + + @Override + public Response> georadius(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { + return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit, param)); + } + + @Override + public Response> georadiusReadonly(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { + return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit, param)); + } + + @Override + public Response> georadiusByMember(String key, String member, double radius, GeoUnit unit) { + return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit)); + } + + @Override + public Response> georadiusByMemberReadonly(String key, String member, double radius, GeoUnit unit) { + return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit)); + } + + @Override + public Response> georadiusByMember(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param) { + return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit, param)); + } + + @Override + public Response> georadiusByMemberReadonly(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param) { + return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit, param)); + } + + @Override + public Response georadiusStore(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { + return appendCommand(commandObjects.georadiusStore(key, longitude, latitude, radius, unit, param, storeParam)); + } + + @Override + public Response georadiusByMemberStore(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { + return appendCommand(commandObjects.georadiusByMemberStore(key, member, radius, unit, param, storeParam)); + } + + @Override + public Response> geosearch(String key, String member, double radius, GeoUnit unit) { + return appendCommand(commandObjects.geosearch(key, member, radius, unit)); + } + + @Override + public Response> geosearch(String key, GeoCoordinate coord, double radius, GeoUnit unit) { + return appendCommand(commandObjects.geosearch(key, coord, radius, unit)); + } + + @Override + public Response> geosearch(String key, String member, double width, double height, GeoUnit unit) { + return appendCommand(commandObjects.geosearch(key, member, width, height, unit)); + } + + @Override + public Response> geosearch(String key, GeoCoordinate coord, double width, double height, GeoUnit unit) { + return appendCommand(commandObjects.geosearch(key, coord, width, height, unit)); + } + + @Override + public Response> geosearch(String key, GeoSearchParam params) { + return appendCommand(commandObjects.geosearch(key, params)); + } + + @Override + public Response geosearchStore(String dest, String src, String member, double radius, GeoUnit unit) { + return appendCommand(commandObjects.geosearchStore(dest, src, member, radius, unit)); + } + + @Override + public Response geosearchStore(String dest, String src, GeoCoordinate coord, double radius, GeoUnit unit) { + return appendCommand(commandObjects.geosearchStore(dest, src, coord, radius, unit)); + } + + @Override + public Response geosearchStore(String dest, String src, String member, double width, double height, GeoUnit unit) { + return appendCommand(commandObjects.geosearchStore(dest, src, member, width, height, unit)); + } + + @Override + public Response geosearchStore(String dest, String src, GeoCoordinate coord, double width, double height, GeoUnit unit) { + return appendCommand(commandObjects.geosearchStore(dest, src, coord, width, height, unit)); + } + + @Override + public Response geosearchStore(String dest, String src, GeoSearchParam params) { + return appendCommand(commandObjects.geosearchStore(dest, src, params)); + } + + @Override + public Response geosearchStoreStoreDist(String dest, String src, GeoSearchParam params) { + return appendCommand(commandObjects.geosearchStoreStoreDist(dest, src, params)); + } + + @Override + public Response pfadd(String key, String... elements) { + return appendCommand(commandObjects.pfadd(key, elements)); + } + + @Override + public Response pfmerge(String destkey, String... sourcekeys) { + return appendCommand(commandObjects.pfmerge(destkey, sourcekeys)); + } + + @Override + public Response pfcount(String key) { + return appendCommand(commandObjects.pfcount(key)); + } + + @Override + public Response pfcount(String... keys) { + return appendCommand(commandObjects.pfcount(keys)); + } + + @Override + public Response xadd(String key, StreamEntryID id, Map hash) { + return appendCommand(commandObjects.xadd(key, id, hash)); + } + + @Override + public Response xadd(String key, XAddParams params, Map hash) { + return appendCommand(commandObjects.xadd(key, params, hash)); + } + + @Override + public Response xlen(String key) { + return appendCommand(commandObjects.xlen(key)); + } + + @Override + public Response> xrange(String key, StreamEntryID start, StreamEntryID end) { + return appendCommand(commandObjects.xrange(key, start, end)); + } + + @Override + public Response> xrange(String key, StreamEntryID start, StreamEntryID end, int count) { + return appendCommand(commandObjects.xrange(key, start, end, count)); + } + + @Override + public Response> xrevrange(String key, StreamEntryID end, StreamEntryID start) { + return appendCommand(commandObjects.xrevrange(key, end, start)); + } + + @Override + public Response> xrevrange(String key, StreamEntryID end, StreamEntryID start, int count) { + return appendCommand(commandObjects.xrevrange(key, end, start, count)); + } + + @Override + public Response> xrange(String key, String start, String end) { + return appendCommand(commandObjects.xrange(key, start, end)); + } + + @Override + public Response> xrange(String key, String start, String end, int count) { + return appendCommand(commandObjects.xrange(key, start, end, count)); + } + + @Override + public Response> xrevrange(String key, String end, String start) { + return appendCommand(commandObjects.xrevrange(key, end, start)); + } + + @Override + public Response> xrevrange(String key, String end, String start, int count) { + return appendCommand(commandObjects.xrevrange(key, end, start, count)); + } + + @Override + public Response xack(String key, String group, StreamEntryID... ids) { + return appendCommand(commandObjects.xack(key, group, ids)); + } + + @Override + public Response xgroupCreate(String key, String groupName, StreamEntryID id, boolean makeStream) { + return appendCommand(commandObjects.xgroupCreate(key, groupName, id, makeStream)); + } + + @Override + public Response xgroupSetID(String key, String groupName, StreamEntryID id) { + return appendCommand(commandObjects.xgroupSetID(key, groupName, id)); + } + + @Override + public Response xgroupDestroy(String key, String groupName) { + return appendCommand(commandObjects.xgroupDestroy(key, groupName)); + } + + @Override + public Response xgroupCreateConsumer(String key, String groupName, String consumerName) { + return appendCommand(commandObjects.xgroupCreateConsumer(key, groupName, consumerName)); + } + + @Override + public Response xgroupDelConsumer(String key, String groupName, String consumerName) { + return appendCommand(commandObjects.xgroupDelConsumer(key, groupName, consumerName)); + } + + @Override + public Response xpending(String key, String groupName) { + return appendCommand(commandObjects.xpending(key, groupName)); + } + + @Override + public Response> xpending(String key, String groupName, XPendingParams params) { + return appendCommand(commandObjects.xpending(key, groupName, params)); + } + + @Override + public Response xdel(String key, StreamEntryID... ids) { + return appendCommand(commandObjects.xdel(key, ids)); + } + + @Override + public Response xtrim(String key, long maxLen, boolean approximate) { + return appendCommand(commandObjects.xtrim(key, maxLen, approximate)); + } + + @Override + public Response xtrim(String key, XTrimParams params) { + return appendCommand(commandObjects.xtrim(key, params)); + } + + @Override + public Response> xclaim(String key, String group, String consumerName, long minIdleTime, XClaimParams params, StreamEntryID... ids) { + return appendCommand(commandObjects.xclaim(key, group, consumerName, minIdleTime, params, ids)); + } + + @Override + public Response> xclaimJustId(String key, String group, String consumerName, long minIdleTime, XClaimParams params, StreamEntryID... ids) { + return appendCommand(commandObjects.xclaimJustId(key, group, consumerName, minIdleTime, params, ids)); + } + + @Override + public Response>> xautoclaim(String key, String group, String consumerName, long minIdleTime, StreamEntryID start, XAutoClaimParams params) { + return appendCommand(commandObjects.xautoclaim(key, group, consumerName, minIdleTime, start, params)); + } + + @Override + public Response>> xautoclaimJustId(String key, String group, String consumerName, long minIdleTime, StreamEntryID start, XAutoClaimParams params) { + return appendCommand(commandObjects.xautoclaimJustId(key, group, consumerName, minIdleTime, start, params)); + } + + @Override + public Response xinfoStream(String key) { + return appendCommand(commandObjects.xinfoStream(key)); + } + + @Override + public Response xinfoStreamFull(String key) { + return appendCommand(commandObjects.xinfoStreamFull(key)); + } + + @Override + public Response xinfoStreamFull(String key, int count) { + return appendCommand(commandObjects.xinfoStreamFull(key, count)); + } + + @Override + public Response> xinfoGroups(String key) { + return appendCommand(commandObjects.xinfoGroups(key)); + } + + @Override + public Response> xinfoConsumers(String key, String group) { + return appendCommand(commandObjects.xinfoConsumers(key, group)); + } + + @Override + public Response> xinfoConsumers2(String key, String group) { + return appendCommand(commandObjects.xinfoConsumers2(key, group)); + } + + @Override + public Response>>> xread(XReadParams xReadParams, Map streams) { + return appendCommand(commandObjects.xread(xReadParams, streams)); + } + + @Override + public Response>>> xreadGroup(String groupName, String consumer, XReadGroupParams xReadGroupParams, Map streams) { + return appendCommand(commandObjects.xreadGroup(groupName, consumer, xReadGroupParams, streams)); + } + + @Override + public Response eval(String script) { + return appendCommand(commandObjects.eval(script)); + } + + @Override + public Response eval(String script, int keyCount, String... params) { + return appendCommand(commandObjects.eval(script, keyCount, params)); + } + + @Override + public Response eval(String script, List keys, List args) { + return appendCommand(commandObjects.eval(script, keys, args)); + } + + @Override + public Response evalReadonly(String script, List keys, List args) { + return appendCommand(commandObjects.evalReadonly(script, keys, args)); + } + + @Override + public Response evalsha(String sha1) { + return appendCommand(commandObjects.evalsha(sha1)); + } + + @Override + public Response evalsha(String sha1, int keyCount, String... params) { + return appendCommand(commandObjects.evalsha(sha1, keyCount, params)); + } + + @Override + public Response evalsha(String sha1, List keys, List args) { + return appendCommand(commandObjects.evalsha(sha1, keys, args)); + } + + @Override + public Response evalshaReadonly(String sha1, List keys, List args) { + return appendCommand(commandObjects.evalshaReadonly(sha1, keys, args)); + } + + @Override + public Response waitReplicas(String sampleKey, int replicas, long timeout) { + return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout)); + } + + @Override + public Response> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout) { + return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout)); + } + + @Override + public Response eval(String script, String sampleKey) { + return appendCommand(commandObjects.eval(script, sampleKey)); + } + + @Override + public Response evalsha(String sha1, String sampleKey) { + return appendCommand(commandObjects.evalsha(sha1, sampleKey)); + } + + @Override + public Response> scriptExists(String sampleKey, String... sha1) { + return appendCommand(commandObjects.scriptExists(sampleKey, sha1)); + } + + @Override + public Response scriptLoad(String script, String sampleKey) { + return appendCommand(commandObjects.scriptLoad(script, sampleKey)); + } + + @Override + public Response scriptFlush(String sampleKey) { + return appendCommand(commandObjects.scriptFlush(sampleKey)); + } + + @Override + public Response scriptFlush(String sampleKey, FlushMode flushMode) { + return appendCommand(commandObjects.scriptFlush(sampleKey, flushMode)); + } + + @Override + public Response scriptKill(String sampleKey) { + return appendCommand(commandObjects.scriptKill(sampleKey)); + } + + @Override + public Response fcall(byte[] name, List keys, List args) { + return appendCommand(commandObjects.fcall(name, keys, args)); + } + + @Override + public Response fcall(String name, List keys, List args) { + return appendCommand(commandObjects.fcall(name, keys, args)); + } + + @Override + public Response fcallReadonly(byte[] name, List keys, List args) { + return appendCommand(commandObjects.fcallReadonly(name, keys, args)); + } + + @Override + public Response fcallReadonly(String name, List keys, List args) { + return appendCommand(commandObjects.fcallReadonly(name, keys, args)); + } + + @Override + public Response functionDelete(byte[] libraryName) { + return appendCommand(commandObjects.functionDelete(libraryName)); + } + + @Override + public Response functionDelete(String libraryName) { + return appendCommand(commandObjects.functionDelete(libraryName)); + } + + @Override + public Response functionDump() { + return appendCommand(commandObjects.functionDump()); + } + + @Override + public Response> functionList(String libraryNamePattern) { + return appendCommand(commandObjects.functionList(libraryNamePattern)); + } + + @Override + public Response> functionList() { + return appendCommand(commandObjects.functionList()); + } + + @Override + public Response> functionListWithCode(String libraryNamePattern) { + return appendCommand(commandObjects.functionListWithCode(libraryNamePattern)); + } + + @Override + public Response> functionListWithCode() { + return appendCommand(commandObjects.functionListWithCode()); + } + + @Override + public Response> functionListBinary() { + return appendCommand(commandObjects.functionListBinary()); + } + + @Override + public Response> functionList(final byte[] libraryNamePattern) { + return appendCommand(commandObjects.functionList(libraryNamePattern)); + } + + @Override + public Response> functionListWithCodeBinary() { + return appendCommand(commandObjects.functionListWithCodeBinary()); + } + + @Override + public Response> functionListWithCode(final byte[] libraryNamePattern) { + return appendCommand(commandObjects.functionListWithCode(libraryNamePattern)); + } + + @Override + public Response functionLoad(byte[] functionCode) { + return appendCommand(commandObjects.functionLoad(functionCode)); + } + + @Override + public Response functionLoad(String functionCode) { + return appendCommand(commandObjects.functionLoad(functionCode)); + } + + @Override + public Response functionLoadReplace(byte[] functionCode) { + return appendCommand(commandObjects.functionLoadReplace(functionCode)); + } + + @Override + public Response functionLoadReplace(String functionCode) { + return appendCommand(commandObjects.functionLoadReplace(functionCode)); + } + + @Override + public Response functionRestore(byte[] serializedValue) { + return appendCommand(commandObjects.functionRestore(serializedValue)); + } + + @Override + public Response functionRestore(byte[] serializedValue, FunctionRestorePolicy policy) { + return appendCommand(commandObjects.functionRestore(serializedValue, policy)); + } + + @Override + public Response functionFlush() { + return appendCommand(commandObjects.functionFlush()); + } + + @Override + public Response functionFlush(FlushMode mode) { + return appendCommand(commandObjects.functionFlush(mode)); + } + + @Override + public Response functionKill() { + return appendCommand(commandObjects.functionKill()); + } + + @Override + public Response functionStats() { + return appendCommand(commandObjects.functionStats()); + } + + @Override + public Response functionStatsBinary() { + return appendCommand(commandObjects.functionStatsBinary()); + } + + @Override + public Response geoadd(byte[] key, double longitude, double latitude, byte[] member) { + return appendCommand(commandObjects.geoadd(key, longitude, latitude, member)); + } + + @Override + public Response geoadd(byte[] key, Map memberCoordinateMap) { + return appendCommand(commandObjects.geoadd(key, memberCoordinateMap)); + } + + @Override + public Response geoadd(byte[] key, GeoAddParams params, Map memberCoordinateMap) { + return appendCommand(commandObjects.geoadd(key, params, memberCoordinateMap)); + } + + @Override + public Response geodist(byte[] key, byte[] member1, byte[] member2) { + return appendCommand(commandObjects.geodist(key, member1, member2)); + } + + @Override + public Response geodist(byte[] key, byte[] member1, byte[] member2, GeoUnit unit) { + return appendCommand(commandObjects.geodist(key, member1, member2, unit)); + } + + @Override + public Response> geohash(byte[] key, byte[]... members) { + return appendCommand(commandObjects.geohash(key, members)); + } + + @Override + public Response> geopos(byte[] key, byte[]... members) { + return appendCommand(commandObjects.geopos(key, members)); + } + + @Override + public Response> georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { + return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit)); + } + + @Override + public Response> georadiusReadonly(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { + return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit)); + } + + @Override + public Response> georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { + return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit, param)); + } + + @Override + public Response> georadiusReadonly(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { + return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit, param)); + } + + @Override + public Response> georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit) { + return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit)); + } + + @Override + public Response> georadiusByMemberReadonly(byte[] key, byte[] member, double radius, GeoUnit unit) { + return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit)); + } + + @Override + public Response> georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { + return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit, param)); + } + + @Override + public Response> georadiusByMemberReadonly(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { + return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit, param)); + } + + @Override + public Response georadiusStore(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { + return appendCommand(commandObjects.georadiusStore(key, longitude, latitude, radius, unit, param, storeParam)); + } + + @Override + public Response georadiusByMemberStore(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { + return appendCommand(commandObjects.georadiusByMemberStore(key, member, radius, unit, param, storeParam)); + } + + @Override + public Response> geosearch(byte[] key, byte[] member, double radius, GeoUnit unit) { + return appendCommand(commandObjects.geosearch(key, member, radius, unit)); + } + + @Override + public Response> geosearch(byte[] key, GeoCoordinate coord, double radius, GeoUnit unit) { + return appendCommand(commandObjects.geosearch(key, coord, radius, unit)); + } + + @Override + public Response> geosearch(byte[] key, byte[] member, double width, double height, GeoUnit unit) { + return appendCommand(commandObjects.geosearch(key, member, width, height, unit)); + } + + @Override + public Response> geosearch(byte[] key, GeoCoordinate coord, double width, double height, GeoUnit unit) { + return appendCommand(commandObjects.geosearch(key, coord, width, height, unit)); + } + + @Override + public Response> geosearch(byte[] key, GeoSearchParam params) { + return appendCommand(commandObjects.geosearch(key, params)); + } + + @Override + public Response geosearchStore(byte[] dest, byte[] src, byte[] member, double radius, GeoUnit unit) { + return appendCommand(commandObjects.geosearchStore(dest, src, member, radius, unit)); + } + + @Override + public Response geosearchStore(byte[] dest, byte[] src, GeoCoordinate coord, double radius, GeoUnit unit) { + return appendCommand(commandObjects.geosearchStore(dest, src, coord, radius, unit)); + } + + @Override + public Response geosearchStore(byte[] dest, byte[] src, byte[] member, double width, double height, GeoUnit unit) { + return appendCommand(commandObjects.geosearchStore(dest, src, member, width, height, unit)); + } + + @Override + public Response geosearchStore(byte[] dest, byte[] src, GeoCoordinate coord, double width, double height, GeoUnit unit) { + return appendCommand(commandObjects.geosearchStore(dest, src, coord, width, height, unit)); + } + + @Override + public Response geosearchStore(byte[] dest, byte[] src, GeoSearchParam params) { + return appendCommand(commandObjects.geosearchStore(dest, src, params)); + } + + @Override + public Response geosearchStoreStoreDist(byte[] dest, byte[] src, GeoSearchParam params) { + return appendCommand(commandObjects.geosearchStoreStoreDist(dest, src, params)); + } + + @Override + public Response hset(byte[] key, byte[] field, byte[] value) { + return appendCommand(commandObjects.hset(key, field, value)); + } + + @Override + public Response hset(byte[] key, Map hash) { + return appendCommand(commandObjects.hset(key, hash)); + } + + @Override + public Response hget(byte[] key, byte[] field) { + return appendCommand(commandObjects.hget(key, field)); + } + + @Override + public Response hsetnx(byte[] key, byte[] field, byte[] value) { + return appendCommand(commandObjects.hsetnx(key, field, value)); + } + + @Override + public Response hmset(byte[] key, Map hash) { + return appendCommand(commandObjects.hmset(key, hash)); + } + + @Override + public Response> hmget(byte[] key, byte[]... fields) { + return appendCommand(commandObjects.hmget(key, fields)); + } + + @Override + public Response hincrBy(byte[] key, byte[] field, long value) { + return appendCommand(commandObjects.hincrBy(key, field, value)); + } + + @Override + public Response hincrByFloat(byte[] key, byte[] field, double value) { + return appendCommand(commandObjects.hincrByFloat(key, field, value)); + } + + @Override + public Response hexists(byte[] key, byte[] field) { + return appendCommand(commandObjects.hexists(key, field)); + } + + @Override + public Response hdel(byte[] key, byte[]... field) { + return appendCommand(commandObjects.hdel(key, field)); + } + + @Override + public Response hlen(byte[] key) { + return appendCommand(commandObjects.hlen(key)); + } + + @Override + public Response> hkeys(byte[] key) { + return appendCommand(commandObjects.hkeys(key)); + } + + @Override + public Response> hvals(byte[] key) { + return appendCommand(commandObjects.hvals(key)); + } + + @Override + public Response> hgetAll(byte[] key) { + return appendCommand(commandObjects.hgetAll(key)); + } + + @Override + public Response hrandfield(byte[] key) { + return appendCommand(commandObjects.hrandfield(key)); + } + + @Override + public Response> hrandfield(byte[] key, long count) { + return appendCommand(commandObjects.hrandfield(key, count)); + } + + @Override + public Response>> hrandfieldWithValues(byte[] key, long count) { + return appendCommand(commandObjects.hrandfieldWithValues(key, count)); + } + + @Override + public Response>> hscan(byte[] key, byte[] cursor, ScanParams params) { + return appendCommand(commandObjects.hscan(key, cursor, params)); + } + + @Override + public Response> hscanNoValues(byte[] key, byte[] cursor, ScanParams params) { + return appendCommand(commandObjects.hscanNoValues(key, cursor, params)); + } + + @Override + public Response hstrlen(byte[] key, byte[] field) { + return appendCommand(commandObjects.hstrlen(key, field)); + } + + @Override + public Response pfadd(byte[] key, byte[]... elements) { + return appendCommand(commandObjects.pfadd(key, elements)); + } + + @Override + public Response pfmerge(byte[] destkey, byte[]... sourcekeys) { + return appendCommand(commandObjects.pfmerge(destkey, sourcekeys)); + } + + @Override + public Response pfcount(byte[] key) { + return appendCommand(commandObjects.pfcount(key)); + } + + @Override + public Response pfcount(byte[]... keys) { + return appendCommand(commandObjects.pfcount(keys)); + } + + @Override + public Response exists(byte[] key) { + return appendCommand(commandObjects.exists(key)); + } + + @Override + public Response exists(byte[]... keys) { + return appendCommand(commandObjects.exists(keys)); + } + + @Override + public Response persist(byte[] key) { + return appendCommand(commandObjects.persist(key)); + } + + @Override + public Response type(byte[] key) { + return appendCommand(commandObjects.type(key)); + } + + @Override + public Response dump(byte[] key) { + return appendCommand(commandObjects.dump(key)); + } + + @Override + public Response restore(byte[] key, long ttl, byte[] serializedValue) { + return appendCommand(commandObjects.restore(key, ttl, serializedValue)); + } + + @Override + public Response restore(byte[] key, long ttl, byte[] serializedValue, RestoreParams params) { + return appendCommand(commandObjects.restore(key, ttl, serializedValue, params)); + } + + @Override + public Response expire(byte[] key, long seconds) { + return appendCommand(commandObjects.expire(key, seconds)); + } + + @Override + public Response expire(byte[] key, long seconds, ExpiryOption expiryOption) { + return appendCommand(commandObjects.expire(key, seconds, expiryOption)); + } + + @Override + public Response pexpire(byte[] key, long milliseconds) { + return appendCommand(commandObjects.pexpire(key, milliseconds)); + } + + @Override + public Response pexpire(byte[] key, long milliseconds, ExpiryOption expiryOption) { + return appendCommand(commandObjects.pexpire(key, milliseconds, expiryOption)); + } + + @Override + public Response expireTime(byte[] key) { + return appendCommand(commandObjects.expireTime(key)); + } + + @Override + public Response pexpireTime(byte[] key) { + return appendCommand(commandObjects.pexpireTime(key)); + } + + @Override + public Response expireAt(byte[] key, long unixTime) { + return appendCommand(commandObjects.expireAt(key, unixTime)); + } + + @Override + public Response expireAt(byte[] key, long unixTime, ExpiryOption expiryOption) { + return appendCommand(commandObjects.expireAt(key, unixTime)); + } + + @Override + public Response pexpireAt(byte[] key, long millisecondsTimestamp) { + return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp)); + } + + @Override + public Response pexpireAt(byte[] key, long millisecondsTimestamp, ExpiryOption expiryOption) { + return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp, expiryOption)); + } + + @Override + public Response ttl(byte[] key) { + return appendCommand(commandObjects.ttl(key)); + } + + @Override + public Response pttl(byte[] key) { + return appendCommand(commandObjects.pttl(key)); + } + + @Override + public Response touch(byte[] key) { + return appendCommand(commandObjects.touch(key)); + } + + @Override + public Response touch(byte[]... keys) { + return appendCommand(commandObjects.touch(keys)); + } + + @Override + public Response> sort(byte[] key) { + return appendCommand(commandObjects.sort(key)); + } + + @Override + public Response> sort(byte[] key, SortingParams sortingParams) { + return appendCommand(commandObjects.sort(key, sortingParams)); + } + + @Override + public Response> sortReadonly(byte[] key, SortingParams sortingParams) { + return appendCommand(commandObjects.sortReadonly(key, sortingParams)); + } + + @Override + public Response del(byte[] key) { + return appendCommand(commandObjects.del(key)); + } + + @Override + public Response del(byte[]... keys) { + return appendCommand(commandObjects.del(keys)); + } + + @Override + public Response unlink(byte[] key) { + return appendCommand(commandObjects.unlink(key)); + } + + @Override + public Response unlink(byte[]... keys) { + return appendCommand(commandObjects.unlink(keys)); + } + + @Override + public Response copy(byte[] srcKey, byte[] dstKey, boolean replace) { + return appendCommand(commandObjects.copy(srcKey, dstKey, replace)); + } + + @Override + public Response rename(byte[] oldkey, byte[] newkey) { + return appendCommand(commandObjects.rename(oldkey, newkey)); + } + + @Override + public Response renamenx(byte[] oldkey, byte[] newkey) { + return appendCommand(commandObjects.renamenx(oldkey, newkey)); + } + + @Override + public Response sort(byte[] key, SortingParams sortingParams, byte[] dstkey) { + return appendCommand(commandObjects.sort(key, sortingParams, dstkey)); + } + + @Override + public Response sort(byte[] key, byte[] dstkey) { + return appendCommand(commandObjects.sort(key, dstkey)); + } + + @Override + public Response memoryUsage(byte[] key) { + return appendCommand(commandObjects.memoryUsage(key)); + } + + @Override + public Response memoryUsage(byte[] key, int samples) { + return appendCommand(commandObjects.memoryUsage(key, samples)); + } + + @Override + public Response objectRefcount(byte[] key) { + return appendCommand(commandObjects.objectRefcount(key)); + } + + @Override + public Response objectEncoding(byte[] key) { + return appendCommand(commandObjects.objectEncoding(key)); + } + + @Override + public Response objectIdletime(byte[] key) { + return appendCommand(commandObjects.objectIdletime(key)); + } + + @Override + public Response objectFreq(byte[] key) { + return appendCommand(commandObjects.objectFreq(key)); + } + + @Override + public Response migrate(String host, int port, byte[] key, int timeout) { + return appendCommand(commandObjects.migrate(host, port, key, timeout)); + } + + @Override + public Response migrate(String host, int port, int timeout, MigrateParams params, byte[]... keys) { + return appendCommand(commandObjects.migrate(host, port, timeout, params, keys)); + } + + @Override + public Response> keys(byte[] pattern) { + return appendCommand(commandObjects.keys(pattern)); + } + + @Override + public Response> scan(byte[] cursor) { + return appendCommand(commandObjects.scan(cursor)); + } + + @Override + public Response> scan(byte[] cursor, ScanParams params) { + return appendCommand(commandObjects.scan(cursor, params)); + } + + @Override + public Response> scan(byte[] cursor, ScanParams params, byte[] type) { + return appendCommand(commandObjects.scan(cursor, params, type)); + } + + @Override + public Response randomBinaryKey() { + return appendCommand(commandObjects.randomBinaryKey()); + } + + @Override + public Response rpush(byte[] key, byte[]... args) { + return appendCommand(commandObjects.rpush(key, args)); + } + + @Override + public Response lpush(byte[] key, byte[]... args) { + return appendCommand(commandObjects.lpush(key, args)); + } + + @Override + public Response llen(byte[] key) { + return appendCommand(commandObjects.llen(key)); + } + + @Override + public Response> lrange(byte[] key, long start, long stop) { + return appendCommand(commandObjects.lrange(key, start, stop)); + } + + @Override + public Response ltrim(byte[] key, long start, long stop) { + return appendCommand(commandObjects.ltrim(key, start, stop)); + } + + @Override + public Response lindex(byte[] key, long index) { + return appendCommand(commandObjects.lindex(key, index)); + } + + @Override + public Response lset(byte[] key, long index, byte[] value) { + return appendCommand(commandObjects.lset(key, index, value)); + } + + @Override + public Response lrem(byte[] key, long count, byte[] value) { + return appendCommand(commandObjects.lrem(key, count, value)); + } + + @Override + public Response lpop(byte[] key) { + return appendCommand(commandObjects.lpop(key)); + } + + @Override + public Response> lpop(byte[] key, int count) { + return appendCommand(commandObjects.lpop(key, count)); + } + + @Override + public Response lpos(byte[] key, byte[] element) { + return appendCommand(commandObjects.lpos(key, element)); + } + + @Override + public Response lpos(byte[] key, byte[] element, LPosParams params) { + return appendCommand(commandObjects.lpos(key, element, params)); + } + + @Override + public Response> lpos(byte[] key, byte[] element, LPosParams params, long count) { + return appendCommand(commandObjects.lpos(key, element, params, count)); + } + + @Override + public Response rpop(byte[] key) { + return appendCommand(commandObjects.rpop(key)); + } + + @Override + public Response> rpop(byte[] key, int count) { + return appendCommand(commandObjects.rpop(key, count)); + } + + @Override + public Response linsert(byte[] key, ListPosition where, byte[] pivot, byte[] value) { + return appendCommand(commandObjects.linsert(key, where, pivot, value)); + } + + @Override + public Response lpushx(byte[] key, byte[]... args) { + return appendCommand(commandObjects.lpushx(key, args)); + } + + @Override + public Response rpushx(byte[] key, byte[]... args) { + return appendCommand(commandObjects.rpushx(key, args)); + } + + @Override + public Response> blpop(int timeout, byte[]... keys) { + return appendCommand(commandObjects.blpop(timeout, keys)); + } + + @Override + public Response> blpop(double timeout, byte[]... keys) { + return appendCommand(commandObjects.blpop(timeout, keys)); + } + + @Override + public Response> brpop(int timeout, byte[]... keys) { + return appendCommand(commandObjects.brpop(timeout, keys)); + } + + @Override + public Response> brpop(double timeout, byte[]... keys) { + return appendCommand(commandObjects.brpop(timeout, keys)); + } + + @Override + public Response rpoplpush(byte[] srckey, byte[] dstkey) { + return appendCommand(commandObjects.rpoplpush(srckey, dstkey)); + } + + @Override + public Response brpoplpush(byte[] source, byte[] destination, int timeout) { + return appendCommand(commandObjects.brpoplpush(source, destination, timeout)); + } + + @Override + public Response lmove(byte[] srcKey, byte[] dstKey, ListDirection from, ListDirection to) { + return appendCommand(commandObjects.lmove(srcKey, dstKey, from, to)); + } + + @Override + public Response blmove(byte[] srcKey, byte[] dstKey, ListDirection from, ListDirection to, double timeout) { + return appendCommand(commandObjects.blmove(srcKey, dstKey, from, to, timeout)); + } + + @Override + public Response>> lmpop(ListDirection direction, byte[]... keys) { + return appendCommand(commandObjects.lmpop(direction, keys)); + } + + @Override + public Response>> lmpop(ListDirection direction, int count, byte[]... keys) { + return appendCommand(commandObjects.lmpop(direction, count, keys)); + } + + @Override + public Response>> blmpop(double timeout, ListDirection direction, byte[]... keys) { + return appendCommand(commandObjects.blmpop(timeout, direction, keys)); + } + + @Override + public Response>> blmpop(double timeout, ListDirection direction, int count, byte[]... keys) { + return appendCommand(commandObjects.blmpop(timeout, direction, count, keys)); + } + + @Override + public Response waitReplicas(byte[] sampleKey, int replicas, long timeout) { + return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout)); + } + + @Override + public Response> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout) { + return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout)); + } + + @Override + public Response eval(byte[] script, byte[] sampleKey) { + return appendCommand(commandObjects.eval(script, sampleKey)); + } + + @Override + public Response evalsha(byte[] sha1, byte[] sampleKey) { + return appendCommand(commandObjects.evalsha(sha1, sampleKey)); + } + + @Override + public Response> scriptExists(byte[] sampleKey, byte[]... sha1s) { + return appendCommand(commandObjects.scriptExists(sampleKey, sha1s)); + } + + @Override + public Response scriptLoad(byte[] script, byte[] sampleKey) { + return appendCommand(commandObjects.scriptLoad(script, sampleKey)); + } + + @Override + public Response scriptFlush(byte[] sampleKey) { + return appendCommand(commandObjects.scriptFlush(sampleKey)); + } + + @Override + public Response scriptFlush(byte[] sampleKey, FlushMode flushMode) { + return appendCommand(commandObjects.scriptFlush(sampleKey, flushMode)); + } + + @Override + public Response scriptKill(byte[] sampleKey) { + return appendCommand(commandObjects.scriptKill(sampleKey)); + } + + @Override + public Response eval(byte[] script) { + return appendCommand(commandObjects.eval(script)); + } + + @Override + public Response eval(byte[] script, int keyCount, byte[]... params) { + return appendCommand(commandObjects.eval(script, keyCount, params)); + } + + @Override + public Response eval(byte[] script, List keys, List args) { + return appendCommand(commandObjects.eval(script, keys, args)); + } + + @Override + public Response evalReadonly(byte[] script, List keys, List args) { + return appendCommand(commandObjects.evalReadonly(script, keys, args)); + } + + @Override + public Response evalsha(byte[] sha1) { + return appendCommand(commandObjects.evalsha(sha1)); + } + + @Override + public Response evalsha(byte[] sha1, int keyCount, byte[]... params) { + return appendCommand(commandObjects.evalsha(sha1, keyCount, params)); + } + + @Override + public Response evalsha(byte[] sha1, List keys, List args) { + return appendCommand(commandObjects.evalsha(sha1, keys, args)); + } + + @Override + public Response evalshaReadonly(byte[] sha1, List keys, List args) { + return appendCommand(commandObjects.evalshaReadonly(sha1, keys, args)); + } + + @Override + public Response sadd(byte[] key, byte[]... members) { + return appendCommand(commandObjects.sadd(key, members)); + } + + @Override + public Response> smembers(byte[] key) { + return appendCommand(commandObjects.smembers(key)); + } + + @Override + public Response srem(byte[] key, byte[]... members) { + return appendCommand(commandObjects.srem(key, members)); + } + + @Override + public Response spop(byte[] key) { + return appendCommand(commandObjects.spop(key)); + } + + @Override + public Response> spop(byte[] key, long count) { + return appendCommand(commandObjects.spop(key, count)); + } + + @Override + public Response scard(byte[] key) { + return appendCommand(commandObjects.scard(key)); + } + + @Override + public Response sismember(byte[] key, byte[] member) { + return appendCommand(commandObjects.sismember(key, member)); + } + + @Override + public Response> smismember(byte[] key, byte[]... members) { + return appendCommand(commandObjects.smismember(key, members)); + } + + @Override + public Response srandmember(byte[] key) { + return appendCommand(commandObjects.srandmember(key)); + } + + @Override + public Response> srandmember(byte[] key, int count) { + return appendCommand(commandObjects.srandmember(key, count)); + } + + @Override + public Response> sscan(byte[] key, byte[] cursor, ScanParams params) { + return appendCommand(commandObjects.sscan(key, cursor, params)); + } + + @Override + public Response> sdiff(byte[]... keys) { + return appendCommand(commandObjects.sdiff(keys)); + } + + @Override + public Response sdiffstore(byte[] dstkey, byte[]... keys) { + return appendCommand(commandObjects.sdiffstore(dstkey, keys)); + } + + @Override + public Response> sinter(byte[]... keys) { + return appendCommand(commandObjects.sinter(keys)); + } + + @Override + public Response sinterstore(byte[] dstkey, byte[]... keys) { + return appendCommand(commandObjects.sinterstore(dstkey, keys)); + } + + @Override + public Response sintercard(byte[]... keys) { + return appendCommand(commandObjects.sintercard(keys)); + } + + @Override + public Response sintercard(int limit, byte[]... keys) { + return appendCommand(commandObjects.sintercard(limit, keys)); + } + + @Override + public Response> sunion(byte[]... keys) { + return appendCommand(commandObjects.sunion(keys)); + } + + @Override + public Response sunionstore(byte[] dstkey, byte[]... keys) { + return appendCommand(commandObjects.sunionstore(dstkey, keys)); + } + + @Override + public Response smove(byte[] srckey, byte[] dstkey, byte[] member) { + return appendCommand(commandObjects.smove(srckey, dstkey, member)); + } + + @Override + public Response zadd(byte[] key, double score, byte[] member) { + return appendCommand(commandObjects.zadd(key, score, member)); + } + + @Override + public Response zadd(byte[] key, double score, byte[] member, ZAddParams params) { + return appendCommand(commandObjects.zadd(key, score, member, params)); + } + + @Override + public Response zadd(byte[] key, Map scoreMembers) { + return appendCommand(commandObjects.zadd(key, scoreMembers)); + } + + @Override + public Response zadd(byte[] key, Map scoreMembers, ZAddParams params) { + return appendCommand(commandObjects.zadd(key, scoreMembers, params)); + } + + @Override + public Response zaddIncr(byte[] key, double score, byte[] member, ZAddParams params) { + return appendCommand(commandObjects.zaddIncr(key, score, member, params)); + } + + @Override + public Response zrem(byte[] key, byte[]... members) { + return appendCommand(commandObjects.zrem(key, members)); + } + + @Override + public Response zincrby(byte[] key, double increment, byte[] member) { + return appendCommand(commandObjects.zincrby(key, increment, member)); + } + + @Override + public Response zincrby(byte[] key, double increment, byte[] member, ZIncrByParams params) { + return appendCommand(commandObjects.zincrby(key, increment, member, params)); + } + + @Override + public Response zrank(byte[] key, byte[] member) { + return appendCommand(commandObjects.zrank(key, member)); + } + + @Override + public Response zrevrank(byte[] key, byte[] member) { + return appendCommand(commandObjects.zrevrank(key, member)); + } + + @Override + public Response> zrankWithScore(byte[] key, byte[] member) { + return appendCommand(commandObjects.zrankWithScore(key, member)); + } + + @Override + public Response> zrevrankWithScore(byte[] key, byte[] member) { + return appendCommand(commandObjects.zrevrankWithScore(key, member)); + } + + @Override + public Response> zrange(byte[] key, long start, long stop) { + return appendCommand(commandObjects.zrange(key, start, stop)); + } + + @Override + public Response> zrevrange(byte[] key, long start, long stop) { + return appendCommand(commandObjects.zrevrange(key, start, stop)); + } + + @Override + public Response> zrangeWithScores(byte[] key, long start, long stop) { + return appendCommand(commandObjects.zrangeWithScores(key, start, stop)); + } + + @Override + public Response> zrevrangeWithScores(byte[] key, long start, long stop) { + return appendCommand(commandObjects.zrevrangeWithScores(key, start, stop)); + } + + @Override + public Response zrandmember(byte[] key) { + return appendCommand(commandObjects.zrandmember(key)); + } + + @Override + public Response> zrandmember(byte[] key, long count) { + return appendCommand(commandObjects.zrandmember(key, count)); + } + + @Override + public Response> zrandmemberWithScores(byte[] key, long count) { + return appendCommand(commandObjects.zrandmemberWithScores(key, count)); + } + + @Override + public Response zcard(byte[] key) { + return appendCommand(commandObjects.zcard(key)); + } + + @Override + public Response zscore(byte[] key, byte[] member) { + return appendCommand(commandObjects.zscore(key, member)); + } + + @Override + public Response> zmscore(byte[] key, byte[]... members) { + return appendCommand(commandObjects.zmscore(key, members)); + } + + @Override + public Response zpopmax(byte[] key) { + return appendCommand(commandObjects.zpopmax(key)); + } + + @Override + public Response> zpopmax(byte[] key, int count) { + return appendCommand(commandObjects.zpopmax(key, count)); + } + + @Override + public Response zpopmin(byte[] key) { + return appendCommand(commandObjects.zpopmin(key)); + } + + @Override + public Response> zpopmin(byte[] key, int count) { + return appendCommand(commandObjects.zpopmin(key, count)); + } + + @Override + public Response zcount(byte[] key, double min, double max) { + return appendCommand(commandObjects.zcount(key, min, max)); + } + + @Override + public Response zcount(byte[] key, byte[] min, byte[] max) { + return appendCommand(commandObjects.zcount(key, min, max)); + } + + @Override + public Response> zrangeByScore(byte[] key, double min, double max) { + return appendCommand(commandObjects.zrangeByScore(key, min, max)); + } + + @Override + public Response> zrangeByScore(byte[] key, byte[] min, byte[] max) { + return appendCommand(commandObjects.zrangeByScore(key, min, max)); + } + + @Override + public Response> zrevrangeByScore(byte[] key, double max, double min) { + return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); + } + + @Override + public Response> zrangeByScore(byte[] key, double min, double max, int offset, int count) { + return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByScore(byte[] key, byte[] max, byte[] min) { + return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); + } + + @Override + public Response> zrangeByScore(byte[] key, byte[] min, byte[] max, int offset, int count) { + return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByScore(byte[] key, double max, double min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); + } + + @Override + public Response> zrangeByScoreWithScores(byte[] key, double min, double max) { + return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); + } + + @Override + public Response> zrevrangeByScoreWithScores(byte[] key, double max, double min) { + return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); + } + + @Override + public Response> zrangeByScoreWithScores(byte[] key, double min, double max, int offset, int count) { + return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByScore(byte[] key, byte[] max, byte[] min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); + } + + @Override + public Response> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max) { + return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); + } + + @Override + public Response> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min) { + return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); + } + + @Override + public Response> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max, int offset, int count) { + return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByScoreWithScores(byte[] key, double max, double min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); + } + + @Override + public Response> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); + } + + @Override + public Response zremrangeByRank(byte[] key, long start, long stop) { + return appendCommand(commandObjects.zremrangeByRank(key, start, stop)); + } + + @Override + public Response zremrangeByScore(byte[] key, double min, double max) { + return appendCommand(commandObjects.zremrangeByScore(key, min, max)); + } + + @Override + public Response zremrangeByScore(byte[] key, byte[] min, byte[] max) { + return appendCommand(commandObjects.zremrangeByScore(key, min, max)); + } + + @Override + public Response zlexcount(byte[] key, byte[] min, byte[] max) { + return appendCommand(commandObjects.zlexcount(key, min, max)); + } + + @Override + public Response> zrangeByLex(byte[] key, byte[] min, byte[] max) { + return appendCommand(commandObjects.zrangeByLex(key, min, max)); + } + + @Override + public Response> zrangeByLex(byte[] key, byte[] min, byte[] max, int offset, int count) { + return appendCommand(commandObjects.zrangeByLex(key, min, max, offset, count)); + } + + @Override + public Response> zrevrangeByLex(byte[] key, byte[] max, byte[] min) { + return appendCommand(commandObjects.zrevrangeByLex(key, max, min)); + } + + @Override + public Response> zrevrangeByLex(byte[] key, byte[] max, byte[] min, int offset, int count) { + return appendCommand(commandObjects.zrevrangeByLex(key, max, min, offset, count)); + } + + @Override + public Response> zrange(byte[] key, ZRangeParams zRangeParams) { + return appendCommand(commandObjects.zrange(key, zRangeParams)); + } + + @Override + public Response> zrangeWithScores(byte[] key, ZRangeParams zRangeParams) { + return appendCommand(commandObjects.zrangeWithScores(key, zRangeParams)); + } + + @Override + public Response zrangestore(byte[] dest, byte[] src, ZRangeParams zRangeParams) { + return appendCommand(commandObjects.zrangestore(dest, src, zRangeParams)); + } + + @Override + public Response zremrangeByLex(byte[] key, byte[] min, byte[] max) { + return appendCommand(commandObjects.zremrangeByLex(key, min, max)); + } + + @Override + public Response> zscan(byte[] key, byte[] cursor, ScanParams params) { + return appendCommand(commandObjects.zscan(key, cursor, params)); + } + + @Override + public Response> bzpopmax(double timeout, byte[]... keys) { + return appendCommand(commandObjects.bzpopmax(timeout, keys)); + } + + @Override + public Response> bzpopmin(double timeout, byte[]... keys) { + return appendCommand(commandObjects.bzpopmin(timeout, keys)); + } + + @Override + public Response>> zmpop(SortedSetOption option, byte[]... keys) { + return appendCommand(commandObjects.zmpop(option, keys)); + } + + @Override + public Response>> zmpop(SortedSetOption option, int count, byte[]... keys) { + return appendCommand(commandObjects.zmpop(option, count, keys)); + } + + @Override + public Response>> bzmpop(double timeout, SortedSetOption option, byte[]... keys) { + return appendCommand(commandObjects.bzmpop(timeout, option, keys)); + } + + @Override + public Response>> bzmpop(double timeout, SortedSetOption option, int count, byte[]... keys) { + return appendCommand(commandObjects.bzmpop(timeout, option, count, keys)); + } + + @Override + public Response> zdiff(byte[]... keys) { + return appendCommand(commandObjects.zdiff(keys)); + } + + @Override + public Response> zdiffWithScores(byte[]... keys) { + return appendCommand(commandObjects.zdiffWithScores(keys)); + } + + @Override + @Deprecated + public Response zdiffStore(byte[] dstkey, byte[]... keys) { + return appendCommand(commandObjects.zdiffStore(dstkey, keys)); + } + + @Override + public Response zdiffstore(byte[] dstkey, byte[]... keys) { + return appendCommand(commandObjects.zdiffstore(dstkey, keys)); + } + + @Override + public Response> zinter(ZParams params, byte[]... keys) { + return appendCommand(commandObjects.zinter(params, keys)); + } + + @Override + public Response> zinterWithScores(ZParams params, byte[]... keys) { + return appendCommand(commandObjects.zinterWithScores(params, keys)); + } + + @Override + public Response zinterstore(byte[] dstkey, byte[]... sets) { + return appendCommand(commandObjects.zinterstore(dstkey, sets)); + } + + @Override + public Response zinterstore(byte[] dstkey, ZParams params, byte[]... sets) { + return appendCommand(commandObjects.zinterstore(dstkey, params, sets)); + } + + @Override + public Response zintercard(byte[]... keys) { + return appendCommand(commandObjects.zintercard(keys)); + } + + @Override + public Response zintercard(long limit, byte[]... keys) { + return appendCommand(commandObjects.zintercard(limit, keys)); + } + + @Override + public Response> zunion(ZParams params, byte[]... keys) { + return appendCommand(commandObjects.zunion(params, keys)); + } + + @Override + public Response> zunionWithScores(ZParams params, byte[]... keys) { + return appendCommand(commandObjects.zunionWithScores(params, keys)); + } + + @Override + public Response zunionstore(byte[] dstkey, byte[]... sets) { + return appendCommand(commandObjects.zunionstore(dstkey, sets)); + } + + @Override + public Response zunionstore(byte[] dstkey, ZParams params, byte[]... sets) { + return appendCommand(commandObjects.zunionstore(dstkey, params, sets)); + } + + @Override + public Response xadd(byte[] key, XAddParams params, Map hash) { + return appendCommand(commandObjects.xadd(key, params, hash)); + } + + @Override + public Response xlen(byte[] key) { + return appendCommand(commandObjects.xlen(key)); + } + + @Override + public Response> xrange(byte[] key, byte[] start, byte[] end) { + return appendCommand(commandObjects.xrange(key, start, end)); + } + + @Override + public Response> xrange(byte[] key, byte[] start, byte[] end, int count) { + return appendCommand(commandObjects.xrange(key, start, end, count)); + } + + @Override + public Response> xrevrange(byte[] key, byte[] end, byte[] start) { + return appendCommand(commandObjects.xrevrange(key, end, start)); + } + + @Override + public Response> xrevrange(byte[] key, byte[] end, byte[] start, int count) { + return appendCommand(commandObjects.xrevrange(key, end, start, count)); + } + + @Override + public Response xack(byte[] key, byte[] group, byte[]... ids) { + return appendCommand(commandObjects.xack(key, group, ids)); + } + + @Override + public Response xgroupCreate(byte[] key, byte[] groupName, byte[] id, boolean makeStream) { + return appendCommand(commandObjects.xgroupCreate(key, groupName, id, makeStream)); + } + + @Override + public Response xgroupSetID(byte[] key, byte[] groupName, byte[] id) { + return appendCommand(commandObjects.xgroupSetID(key, groupName, id)); + } + + @Override + public Response xgroupDestroy(byte[] key, byte[] groupName) { + return appendCommand(commandObjects.xgroupDestroy(key, groupName)); + } + + @Override + public Response xgroupCreateConsumer(byte[] key, byte[] groupName, byte[] consumerName) { + return appendCommand(commandObjects.xgroupCreateConsumer(key, groupName, consumerName)); + } + + @Override + public Response xgroupDelConsumer(byte[] key, byte[] groupName, byte[] consumerName) { + return appendCommand(commandObjects.xgroupDelConsumer(key, groupName, consumerName)); + } + + @Override + public Response xdel(byte[] key, byte[]... ids) { + return appendCommand(commandObjects.xdel(key, ids)); + } + + @Override + public Response xtrim(byte[] key, long maxLen, boolean approximateLength) { + return appendCommand(commandObjects.xtrim(key, maxLen, approximateLength)); + } + + @Override + public Response xtrim(byte[] key, XTrimParams params) { + return appendCommand(commandObjects.xtrim(key, params)); + } + + @Override + public Response xpending(byte[] key, byte[] groupName) { + return appendCommand(commandObjects.xpending(key, groupName)); + } + + @Override + public Response> xpending(byte[] key, byte[] groupName, XPendingParams params) { + return appendCommand(commandObjects.xpending(key, groupName, params)); + } + + @Override + public Response> xclaim(byte[] key, byte[] group, byte[] consumerName, long minIdleTime, XClaimParams params, byte[]... ids) { + return appendCommand(commandObjects.xclaim(key, group, consumerName, minIdleTime, params, ids)); + } + + @Override + public Response> xclaimJustId(byte[] key, byte[] group, byte[] consumerName, long minIdleTime, XClaimParams params, byte[]... ids) { + return appendCommand(commandObjects.xclaimJustId(key, group, consumerName, minIdleTime, params, ids)); + } + + @Override + public Response> xautoclaim(byte[] key, byte[] groupName, byte[] consumerName, long minIdleTime, byte[] start, XAutoClaimParams params) { + return appendCommand(commandObjects.xautoclaim(key, groupName, consumerName, minIdleTime, start, params)); + } + + @Override + public Response> xautoclaimJustId(byte[] key, byte[] groupName, byte[] consumerName, long minIdleTime, byte[] start, XAutoClaimParams params) { + return appendCommand(commandObjects.xautoclaimJustId(key, groupName, consumerName, minIdleTime, start, params)); + } + + @Override + public Response xinfoStream(byte[] key) { + return appendCommand(commandObjects.xinfoStream(key)); + } + + @Override + public Response xinfoStreamFull(byte[] key) { + return appendCommand(commandObjects.xinfoStreamFull(key)); + } + + @Override + public Response xinfoStreamFull(byte[] key, int count) { + return appendCommand(commandObjects.xinfoStreamFull(key, count)); + } + + @Override + public Response> xinfoGroups(byte[] key) { + return appendCommand(commandObjects.xinfoGroups(key)); + } + + @Override + public Response> xinfoConsumers(byte[] key, byte[] group) { + return appendCommand(commandObjects.xinfoConsumers(key, group)); + } + + @Override + public Response> xread(XReadParams xReadParams, Map.Entry... streams) { + return appendCommand(commandObjects.xread(xReadParams, streams)); + } + + @Override + public Response> xreadGroup(byte[] groupName, byte[] consumer, + XReadGroupParams xReadGroupParams, Map.Entry... streams) { + return appendCommand(commandObjects.xreadGroup(groupName, consumer, xReadGroupParams, streams)); + } + + @Override + public Response set(byte[] key, byte[] value) { + return appendCommand(commandObjects.set(key, value)); + } + + @Override + public Response set(byte[] key, byte[] value, SetParams params) { + return appendCommand(commandObjects.set(key, value, params)); + } + + @Override + public Response get(byte[] key) { + return appendCommand(commandObjects.get(key)); + } + + @Override + public Response setGet(byte[] key, byte[] value, SetParams params) { + return appendCommand(commandObjects.setGet(key, value, params)); + } + + @Override + public Response getDel(byte[] key) { + return appendCommand(commandObjects.getDel(key)); + } + + @Override + public Response getEx(byte[] key, GetExParams params) { + return appendCommand(commandObjects.getEx(key, params)); + } + + @Override + public Response setbit(byte[] key, long offset, boolean value) { + return appendCommand(commandObjects.setbit(key, offset, value)); + } + + @Override + public Response getbit(byte[] key, long offset) { + return appendCommand(commandObjects.getbit(key, offset)); + } + + @Override + public Response setrange(byte[] key, long offset, byte[] value) { + return appendCommand(commandObjects.setrange(key, offset, value)); + } + + @Override + public Response getrange(byte[] key, long startOffset, long endOffset) { + return appendCommand(commandObjects.getrange(key, startOffset, endOffset)); + } + + @Override + public Response getSet(byte[] key, byte[] value) { + return appendCommand(commandObjects.getSet(key, value)); + } + + @Override + public Response setnx(byte[] key, byte[] value) { + return appendCommand(commandObjects.setnx(key, value)); + } + + @Override + public Response setex(byte[] key, long seconds, byte[] value) { + return appendCommand(commandObjects.setex(key, seconds, value)); + } + + @Override + public Response psetex(byte[] key, long milliseconds, byte[] value) { + return appendCommand(commandObjects.psetex(key, milliseconds, value)); + } + + @Override + public Response> mget(byte[]... keys) { + return appendCommand(commandObjects.mget(keys)); + } + + @Override + public Response mset(byte[]... keysvalues) { + return appendCommand(commandObjects.mset(keysvalues)); + } + + @Override + public Response msetnx(byte[]... keysvalues) { + return appendCommand(commandObjects.msetnx(keysvalues)); + } + + @Override + public Response incr(byte[] key) { + return appendCommand(commandObjects.incr(key)); + } + + @Override + public Response incrBy(byte[] key, long increment) { + return appendCommand(commandObjects.incrBy(key, increment)); + } + + @Override + public Response incrByFloat(byte[] key, double increment) { + return appendCommand(commandObjects.incrByFloat(key, increment)); + } + + @Override + public Response decr(byte[] key) { + return appendCommand(commandObjects.decr(key)); + } + + @Override + public Response decrBy(byte[] key, long decrement) { + return appendCommand(commandObjects.decrBy(key, decrement)); + } + + @Override + public Response append(byte[] key, byte[] value) { + return appendCommand(commandObjects.append(key, value)); + } + + @Override + public Response substr(byte[] key, int start, int end) { + return appendCommand(commandObjects.substr(key, start, end)); + } + + @Override + public Response strlen(byte[] key) { + return appendCommand(commandObjects.strlen(key)); + } + + @Override + public Response bitcount(byte[] key) { + return appendCommand(commandObjects.bitcount(key)); + } + + @Override + public Response bitcount(byte[] key, long start, long end) { + return appendCommand(commandObjects.bitcount(key, start, end)); + } + + @Override + public Response bitcount(byte[] key, long start, long end, BitCountOption option) { + return appendCommand(commandObjects.bitcount(key, start, end, option)); + } + + @Override + public Response bitpos(byte[] key, boolean value) { + return appendCommand(commandObjects.bitpos(key, value)); + } + + @Override + public Response bitpos(byte[] key, boolean value, BitPosParams params) { + return appendCommand(commandObjects.bitpos(key, value, params)); + } + + @Override + public Response> bitfield(byte[] key, byte[]... arguments) { + return appendCommand(commandObjects.bitfield(key, arguments)); + } + + @Override + public Response> bitfieldReadonly(byte[] key, byte[]... arguments) { + return appendCommand(commandObjects.bitfieldReadonly(key, arguments)); + } + + @Override + public Response bitop(BitOP op, byte[] destKey, byte[]... srcKeys) { + return appendCommand(commandObjects.bitop(op, destKey, srcKeys)); + } + + // RediSearch commands + @Override + public Response ftCreate(String indexName, IndexOptions indexOptions, Schema schema) { + return appendCommand(commandObjects.ftCreate(indexName, indexOptions, schema)); + } + + @Override + public Response ftCreate(String indexName, FTCreateParams createParams, Iterable schemaFields) { + return appendCommand(commandObjects.ftCreate(indexName, createParams, schemaFields)); + } + + @Override + public Response ftAlter(String indexName, Schema schema) { + return appendCommand(commandObjects.ftAlter(indexName, schema)); + } + + @Override + public Response ftAlter(String indexName, Iterable schemaFields) { + return appendCommand(commandObjects.ftAlter(indexName, schemaFields)); + } + + @Override + public Response ftAliasAdd(String aliasName, String indexName) { + return appendCommand(commandObjects.ftAliasAdd(aliasName, indexName)); + } + + @Override + public Response ftAliasUpdate(String aliasName, String indexName) { + return appendCommand(commandObjects.ftAliasUpdate(aliasName, indexName)); + } + + @Override + public Response ftAliasDel(String aliasName) { + return appendCommand(commandObjects.ftAliasDel(aliasName)); + } + + @Override + public Response ftDropIndex(String indexName) { + return appendCommand(commandObjects.ftDropIndex(indexName)); + } + + @Override + public Response ftDropIndexDD(String indexName) { + return appendCommand(commandObjects.ftDropIndexDD(indexName)); + } + + @Override + public Response ftSearch(String indexName, String query) { + return appendCommand(commandObjects.ftSearch(indexName, query)); + } + + @Override + public Response ftSearch(String indexName, String query, FTSearchParams searchParams) { + return appendCommand(commandObjects.ftSearch(indexName, query, searchParams)); + } + + @Override + public Response ftSearch(String indexName, Query query) { + return appendCommand(commandObjects.ftSearch(indexName, query)); + } + + @Override + @Deprecated + public Response ftSearch(byte[] indexName, Query query) { + return appendCommand(commandObjects.ftSearch(indexName, query)); + } + + @Override + public Response ftExplain(String indexName, Query query) { + return appendCommand(commandObjects.ftExplain(indexName, query)); + } + + @Override + public Response> ftExplainCLI(String indexName, Query query) { + return appendCommand(commandObjects.ftExplainCLI(indexName, query)); + } + + @Override + public Response ftAggregate(String indexName, AggregationBuilder aggr) { + return appendCommand(commandObjects.ftAggregate(indexName, aggr)); + } + + @Override + public Response ftSynUpdate(String indexName, String synonymGroupId, String... terms) { + return appendCommand(commandObjects.ftSynUpdate(indexName, synonymGroupId, terms)); + } + + @Override + public Response>> ftSynDump(String indexName) { + return appendCommand(commandObjects.ftSynDump(indexName)); + } + + @Override + public Response ftDictAdd(String dictionary, String... terms) { + return appendCommand(commandObjects.ftDictAdd(dictionary, terms)); + } + + @Override + public Response ftDictDel(String dictionary, String... terms) { + return appendCommand(commandObjects.ftDictDel(dictionary, terms)); + } + + @Override + public Response> ftDictDump(String dictionary) { + return appendCommand(commandObjects.ftDictDump(dictionary)); + } + + @Override + public Response ftDictAddBySampleKey(String indexName, String dictionary, String... terms) { + return appendCommand(commandObjects.ftDictAddBySampleKey(indexName, dictionary, terms)); + } + + @Override + public Response ftDictDelBySampleKey(String indexName, String dictionary, String... terms) { + return appendCommand(commandObjects.ftDictDelBySampleKey(indexName, dictionary, terms)); + } + + @Override + public Response> ftDictDumpBySampleKey(String indexName, String dictionary) { + return appendCommand(commandObjects.ftDictDumpBySampleKey(indexName, dictionary)); + } + + @Override + public Response>> ftSpellCheck(String index, String query) { + return appendCommand(commandObjects.ftSpellCheck(index, query)); + } + + @Override + public Response>> ftSpellCheck(String index, String query, FTSpellCheckParams spellCheckParams) { + return appendCommand(commandObjects.ftSpellCheck(index, query, spellCheckParams)); + } + + @Override + public Response> ftInfo(String indexName) { + return appendCommand(commandObjects.ftInfo(indexName)); + } + + @Override + public Response> ftTagVals(String indexName, String fieldName) { + return appendCommand(commandObjects.ftTagVals(indexName, fieldName)); + } + + @Override + public Response> ftConfigGet(String option) { + return appendCommand(commandObjects.ftConfigGet(option)); + } + + @Override + public Response> ftConfigGet(String indexName, String option) { + return appendCommand(commandObjects.ftConfigGet(indexName, option)); + } + + @Override + public Response ftConfigSet(String option, String value) { + return appendCommand(commandObjects.ftConfigSet(option, value)); + } + + @Override + public Response ftConfigSet(String indexName, String option, String value) { + return appendCommand(commandObjects.ftConfigSet(indexName, option, value)); + } + + @Override + public Response ftSugAdd(String key, String string, double score) { + return appendCommand(commandObjects.ftSugAdd(key, string, score)); + } + + @Override + public Response ftSugAddIncr(String key, String string, double score) { + return appendCommand(commandObjects.ftSugAddIncr(key, string, score)); + } + + @Override + public Response> ftSugGet(String key, String prefix) { + return appendCommand(commandObjects.ftSugGet(key, prefix)); + } + + @Override + public Response> ftSugGet(String key, String prefix, boolean fuzzy, int max) { + return appendCommand(commandObjects.ftSugGet(key, prefix, fuzzy, max)); + } + + @Override + public Response> ftSugGetWithScores(String key, String prefix) { + return appendCommand(commandObjects.ftSugGetWithScores(key, prefix)); + } + + @Override + public Response> ftSugGetWithScores(String key, String prefix, boolean fuzzy, int max) { + return appendCommand(commandObjects.ftSugGetWithScores(key, prefix, fuzzy, max)); + } + + @Override + public Response ftSugDel(String key, String string) { + return appendCommand(commandObjects.ftSugDel(key, string)); + } + + @Override + public Response ftSugLen(String key) { + return appendCommand(commandObjects.ftSugLen(key)); + } + // RediSearch commands + + // RedisJSON commands + @Override + public Response lcs(byte[] keyA, byte[] keyB, LCSParams params) { + return appendCommand(commandObjects.lcs(keyA, keyB, params)); + } + + @Override + public Response jsonSet(String key, Path2 path, Object object) { + return appendCommand(commandObjects.jsonSet(key, path, object)); + } + + @Override + public Response jsonSetWithEscape(String key, Path2 path, Object object) { + return appendCommand(commandObjects.jsonSetWithEscape(key, path, object)); + } + + @Override + public Response jsonSet(String key, Path path, Object object) { + return appendCommand(commandObjects.jsonSet(key, path, object)); + } + + @Override + public Response jsonSet(String key, Path2 path, Object object, JsonSetParams params) { + return appendCommand(commandObjects.jsonSet(key, path, object, params)); + } + + @Override + public Response jsonSetWithEscape(String key, Path2 path, Object object, JsonSetParams params) { + return appendCommand(commandObjects.jsonSetWithEscape(key, path, object, params)); + } + + @Override + public Response jsonSet(String key, Path path, Object object, JsonSetParams params) { + return appendCommand(commandObjects.jsonSet(key, path, object, params)); + } + + @Override + public Response jsonMerge(String key, Path2 path, Object object) { + return appendCommand(commandObjects.jsonMerge(key, path, object)); + } + + @Override + public Response jsonMerge(String key, Path path, Object object) { + return appendCommand(commandObjects.jsonMerge(key, path, object)); + } + + @Override + public Response jsonGet(String key) { + return appendCommand(commandObjects.jsonGet(key)); + } + + @Override + public Response jsonGet(String key, Class clazz) { + return appendCommand(commandObjects.jsonGet(key, clazz)); + } + + @Override + public Response jsonGet(String key, Path2... paths) { + return appendCommand(commandObjects.jsonGet(key, paths)); + } + + @Override + public Response jsonGet(String key, Path... paths) { + return appendCommand(commandObjects.jsonGet(key, paths)); + } + + @Override + public Response jsonGet(String key, Class clazz, Path... paths) { + return appendCommand(commandObjects.jsonGet(key, clazz, paths)); + } + + @Override + public Response> jsonMGet(Path2 path, String... keys) { + return appendCommand(commandObjects.jsonMGet(path, keys)); + } + + @Override + public Response> jsonMGet(Path path, Class clazz, String... keys) { + return appendCommand(commandObjects.jsonMGet(path, clazz, keys)); + } + + @Override + public Response jsonDel(String key) { + return appendCommand(commandObjects.jsonDel(key)); + } + + @Override + public Response jsonDel(String key, Path2 path) { + return appendCommand(commandObjects.jsonDel(key, path)); + } + + @Override + public Response jsonDel(String key, Path path) { + return appendCommand(commandObjects.jsonDel(key, path)); + } + + @Override + public Response jsonClear(String key) { + return appendCommand(commandObjects.jsonClear(key)); + } + + @Override + public Response jsonClear(String key, Path2 path) { + return appendCommand(commandObjects.jsonClear(key, path)); + } + + @Override + public Response jsonClear(String key, Path path) { + return appendCommand(commandObjects.jsonClear(key, path)); + } + + @Override + public Response> jsonToggle(String key, Path2 path) { + return appendCommand(commandObjects.jsonToggle(key, path)); + } + + @Override + public Response jsonToggle(String key, Path path) { + return appendCommand(commandObjects.jsonToggle(key, path)); + } + + @Override + public Response> jsonType(String key) { + return appendCommand(commandObjects.jsonType(key)); + } + + @Override + public Response>> jsonType(String key, Path2 path) { + return appendCommand(commandObjects.jsonType(key, path)); + } + + @Override + public Response> jsonType(String key, Path path) { + return appendCommand(commandObjects.jsonType(key, path)); + } + + @Override + public Response jsonStrAppend(String key, Object string) { + return appendCommand(commandObjects.jsonStrAppend(key, string)); + } + + @Override + public Response> jsonStrAppend(String key, Path2 path, Object string) { + return appendCommand(commandObjects.jsonStrAppend(key, path, string)); + } + + @Override + public Response jsonStrAppend(String key, Path path, Object string) { + return appendCommand(commandObjects.jsonStrAppend(key, path, string)); + } + + @Override + public Response jsonStrLen(String key) { + return appendCommand(commandObjects.jsonStrLen(key)); + } + + @Override + public Response> jsonStrLen(String key, Path2 path) { + return appendCommand(commandObjects.jsonStrLen(key, path)); + } + + @Override + public Response jsonStrLen(String key, Path path) { + return appendCommand(commandObjects.jsonStrLen(key, path)); + } + + @Override + public Response jsonNumIncrBy(String key, Path2 path, double value) { + return appendCommand(commandObjects.jsonNumIncrBy(key, path, value)); + } + + @Override + public Response jsonNumIncrBy(String key, Path path, double value) { + return appendCommand(commandObjects.jsonNumIncrBy(key, path, value)); + } + + @Override + public Response> jsonArrAppend(String key, Path2 path, Object... objects) { + return appendCommand(commandObjects.jsonArrAppend(key, path, objects)); + } + + @Override + public Response> jsonArrAppendWithEscape(String key, Path2 path, Object... objects) { + return appendCommand(commandObjects.jsonArrAppendWithEscape(key, path, objects)); + } + + @Override + public Response jsonArrAppend(String key, Path path, Object... objects) { + return appendCommand(commandObjects.jsonArrAppend(key, path, objects)); + } + + @Override + public Response> jsonArrIndex(String key, Path2 path, Object scalar) { + return appendCommand(commandObjects.jsonArrIndex(key, path, scalar)); + } + + @Override + public Response> jsonArrIndexWithEscape(String key, Path2 path, Object scalar) { + return appendCommand(commandObjects.jsonArrIndexWithEscape(key, path, scalar)); + } + + @Override + public Response jsonArrIndex(String key, Path path, Object scalar) { + return appendCommand(commandObjects.jsonArrIndex(key, path, scalar)); + } + + @Override + public Response> jsonArrInsert(String key, Path2 path, int index, Object... objects) { + return appendCommand(commandObjects.jsonArrInsert(key, path, index, objects)); + } + + @Override + public Response> jsonArrInsertWithEscape(String key, Path2 path, int index, Object... objects) { + return appendCommand(commandObjects.jsonArrInsertWithEscape(key, path, index, objects)); + } + + @Override + public Response jsonArrInsert(String key, Path path, int index, Object... pojos) { + return appendCommand(commandObjects.jsonArrInsert(key, path, index, pojos)); + } + + @Override + public Response jsonArrPop(String key) { + return appendCommand(commandObjects.jsonArrPop(key)); + } + + @Override + public Response jsonArrLen(String key, Path path) { + return appendCommand(commandObjects.jsonArrLen(key, path)); + } + + @Override + public Response> jsonArrTrim(String key, Path2 path, int start, int stop) { + return appendCommand(commandObjects.jsonArrTrim(key, path, start, stop)); + } + + @Override + public Response jsonArrTrim(String key, Path path, int start, int stop) { + return appendCommand(commandObjects.jsonArrTrim(key, path, start, stop)); + } + + @Override + public Response jsonArrPop(String key, Class clazz, Path path) { + return appendCommand(commandObjects.jsonArrPop(key, clazz, path)); + } + + @Override + public Response> jsonArrPop(String key, Path2 path, int index) { + return appendCommand(commandObjects.jsonArrPop(key, path, index)); + } + + @Override + public Response jsonArrPop(String key, Path path, int index) { + return appendCommand(commandObjects.jsonArrPop(key, path, index)); + } + + @Override + public Response jsonArrPop(String key, Class clazz, Path path, int index) { + return appendCommand(commandObjects.jsonArrPop(key, clazz, path, index)); + } + + @Override + public Response jsonArrLen(String key) { + return appendCommand(commandObjects.jsonArrLen(key)); + } + + @Override + public Response> jsonArrLen(String key, Path2 path) { + return appendCommand(commandObjects.jsonArrLen(key, path)); + } + + @Override + public Response jsonArrPop(String key, Class clazz) { + return appendCommand(commandObjects.jsonArrPop(key, clazz)); + } + + @Override + public Response> jsonArrPop(String key, Path2 path) { + return appendCommand(commandObjects.jsonArrPop(key, path)); + } + + @Override + public Response jsonArrPop(String key, Path path) { + return appendCommand(commandObjects.jsonArrPop(key, path)); + } + // RedisJSON commands + + // RedisTimeSeries commands + @Override + public Response tsCreate(String key) { + return appendCommand(commandObjects.tsCreate(key)); + } + + @Override + public Response tsCreate(String key, TSCreateParams createParams) { + return appendCommand(commandObjects.tsCreate(key, createParams)); + } + + @Override + public Response tsDel(String key, long fromTimestamp, long toTimestamp) { + return appendCommand(commandObjects.tsDel(key, fromTimestamp, toTimestamp)); + } + + @Override + public Response tsAlter(String key, TSAlterParams alterParams) { + return appendCommand(commandObjects.tsAlter(key, alterParams)); + } + + @Override + public Response tsAdd(String key, double value) { + return appendCommand(commandObjects.tsAdd(key, value)); + } + + @Override + public Response tsAdd(String key, long timestamp, double value) { + return appendCommand(commandObjects.tsAdd(key, timestamp, value)); + } + + @Override + public Response tsAdd(String key, long timestamp, double value, TSCreateParams createParams) { + return appendCommand(commandObjects.tsAdd(key, timestamp, value, createParams)); + } + + @Override + public Response> tsMAdd(Map.Entry... entries) { + return appendCommand(commandObjects.tsMAdd(entries)); + } + + @Override + public Response tsIncrBy(String key, double value) { + return appendCommand(commandObjects.tsIncrBy(key, value)); + } + + @Override + public Response tsIncrBy(String key, double value, long timestamp) { + return appendCommand(commandObjects.tsIncrBy(key, value, timestamp)); + } + + @Override + public Response tsDecrBy(String key, double value) { + return appendCommand(commandObjects.tsDecrBy(key, value)); + } + + @Override + public Response tsDecrBy(String key, double value, long timestamp) { + return appendCommand(commandObjects.tsDecrBy(key, value, timestamp)); + } + + @Override + public Response> tsRange(String key, long fromTimestamp, long toTimestamp) { + return appendCommand(commandObjects.tsRange(key, fromTimestamp, toTimestamp)); + } + + @Override + public Response> tsRange(String key, TSRangeParams rangeParams) { + return appendCommand(commandObjects.tsRange(key, rangeParams)); + } + + @Override + public Response> tsRevRange(String key, long fromTimestamp, long toTimestamp) { + return appendCommand(commandObjects.tsRevRange(key, fromTimestamp, toTimestamp)); + } + + @Override + public Response> tsRevRange(String key, TSRangeParams rangeParams) { + return appendCommand(commandObjects.tsRevRange(key, rangeParams)); + } + + @Override + public Response> tsMRange(long fromTimestamp, long toTimestamp, String... filters) { + return appendCommand(commandObjects.tsMRange(fromTimestamp, toTimestamp, filters)); + } + + @Override + public Response> tsMRange(TSMRangeParams multiRangeParams) { + return appendCommand(commandObjects.tsMRange(multiRangeParams)); + } + + @Override + public Response> tsMRevRange(long fromTimestamp, long toTimestamp, String... filters) { + return appendCommand(commandObjects.tsMRevRange(fromTimestamp, toTimestamp, filters)); + } + + @Override + public Response> tsMRevRange(TSMRangeParams multiRangeParams) { + return appendCommand(commandObjects.tsMRevRange(multiRangeParams)); + } + + @Override + public Response tsGet(String key) { + return appendCommand(commandObjects.tsGet(key)); + } + + @Override + public Response tsGet(String key, TSGetParams getParams) { + return appendCommand(commandObjects.tsGet(key, getParams)); + } + + @Override + public Response> tsMGet(TSMGetParams multiGetParams, String... filters) { + return appendCommand(commandObjects.tsMGet(multiGetParams, filters)); + } + + @Override + public Response tsCreateRule(String sourceKey, String destKey, AggregationType aggregationType, long timeBucket) { + return appendCommand(commandObjects.tsCreateRule(sourceKey, destKey, aggregationType, timeBucket)); + } + + @Override + public Response tsCreateRule(String sourceKey, String destKey, AggregationType aggregationType, long bucketDuration, long alignTimestamp) { + return appendCommand(commandObjects.tsCreateRule(sourceKey, destKey, aggregationType, bucketDuration, alignTimestamp)); + } + + @Override + public Response tsDeleteRule(String sourceKey, String destKey) { + return appendCommand(commandObjects.tsDeleteRule(sourceKey, destKey)); + } + + @Override + public Response> tsQueryIndex(String... filters) { + return appendCommand(commandObjects.tsQueryIndex(filters)); + } + // RedisTimeSeries commands + + // RedisBloom commands + @Override + public Response bfReserve(String key, double errorRate, long capacity) { + return appendCommand(commandObjects.bfReserve(key, errorRate, capacity)); + } + + @Override + public Response bfReserve(String key, double errorRate, long capacity, BFReserveParams reserveParams) { + return appendCommand(commandObjects.bfReserve(key, errorRate, capacity, reserveParams)); + } + + @Override + public Response bfAdd(String key, String item) { + return appendCommand(commandObjects.bfAdd(key, item)); + } + + @Override + public Response> bfMAdd(String key, String... items) { + return appendCommand(commandObjects.bfMAdd(key, items)); + } + + @Override + public Response> bfInsert(String key, String... items) { + return appendCommand(commandObjects.bfInsert(key, items)); + } + + @Override + public Response> bfInsert(String key, BFInsertParams insertParams, String... items) { + return appendCommand(commandObjects.bfInsert(key, insertParams, items)); + } + + @Override + public Response bfExists(String key, String item) { + return appendCommand(commandObjects.bfExists(key, item)); + } + + @Override + public Response> bfMExists(String key, String... items) { + return appendCommand(commandObjects.bfMExists(key, items)); + } + + @Override + public Response> bfScanDump(String key, long iterator) { + return appendCommand(commandObjects.bfScanDump(key, iterator)); + } + + @Override + public Response bfLoadChunk(String key, long iterator, byte[] data) { + return appendCommand(commandObjects.bfLoadChunk(key, iterator, data)); + } + + @Override + public Response bfCard(String key) { + return appendCommand(commandObjects.bfCard(key)); + } + + @Override + public Response> bfInfo(String key) { + return appendCommand(commandObjects.bfInfo(key)); + } + + @Override + public Response cfReserve(String key, long capacity) { + return appendCommand(commandObjects.cfReserve(key, capacity)); + } + + @Override + public Response cfReserve(String key, long capacity, CFReserveParams reserveParams) { + return appendCommand(commandObjects.cfReserve(key, capacity, reserveParams)); + } + + @Override + public Response cfAdd(String key, String item) { + return appendCommand(commandObjects.cfAdd(key, item)); + } + + @Override + public Response cfAddNx(String key, String item) { + return appendCommand(commandObjects.cfAddNx(key, item)); + } + + @Override + public Response> cfInsert(String key, String... items) { + return appendCommand(commandObjects.cfInsert(key, items)); + } + + @Override + public Response> cfInsert(String key, CFInsertParams insertParams, String... items) { + return appendCommand(commandObjects.cfInsert(key, insertParams, items)); + } + + @Override + public Response> cfInsertNx(String key, String... items) { + return appendCommand(commandObjects.cfInsertNx(key, items)); + } + + @Override + public Response> cfInsertNx(String key, CFInsertParams insertParams, String... items) { + return appendCommand(commandObjects.cfInsertNx(key, insertParams, items)); + } + + @Override + public Response cfExists(String key, String item) { + return appendCommand(commandObjects.cfExists(key, item)); + } + + @Override + public Response cfDel(String key, String item) { + return appendCommand(commandObjects.cfDel(key, item)); + } + + @Override + public Response cfCount(String key, String item) { + return appendCommand(commandObjects.cfCount(key, item)); + } + + @Override + public Response> cfScanDump(String key, long iterator) { + return appendCommand(commandObjects.cfScanDump(key, iterator)); + } + + @Override + public Response cfLoadChunk(String key, long iterator, byte[] data) { + return appendCommand(commandObjects.cfLoadChunk(key, iterator, data)); + } + + @Override + public Response> cfInfo(String key) { + return appendCommand(commandObjects.cfInfo(key)); + } + + @Override + public Response cmsInitByDim(String key, long width, long depth) { + return appendCommand(commandObjects.cmsInitByDim(key, width, depth)); + } + + @Override + public Response cmsInitByProb(String key, double error, double probability) { + return appendCommand(commandObjects.cmsInitByProb(key, error, probability)); + } + + @Override + public Response> cmsIncrBy(String key, Map itemIncrements) { + return appendCommand(commandObjects.cmsIncrBy(key, itemIncrements)); + } + + @Override + public Response> cmsQuery(String key, String... items) { + return appendCommand(commandObjects.cmsQuery(key, items)); + } + + @Override + public Response cmsMerge(String destKey, String... keys) { + return appendCommand(commandObjects.cmsMerge(destKey, keys)); + } + + @Override + public Response cmsMerge(String destKey, Map keysAndWeights) { + return appendCommand(commandObjects.cmsMerge(destKey, keysAndWeights)); + } + + @Override + public Response> cmsInfo(String key) { + return appendCommand(commandObjects.cmsInfo(key)); + } + + @Override + public Response topkReserve(String key, long topk) { + return appendCommand(commandObjects.topkReserve(key, topk)); + } + + @Override + public Response topkReserve(String key, long topk, long width, long depth, double decay) { + return appendCommand(commandObjects.topkReserve(key, topk, width, depth, decay)); + } + + @Override + public Response> topkAdd(String key, String... items) { + return appendCommand(commandObjects.topkAdd(key, items)); + } + + @Override + public Response> topkIncrBy(String key, Map itemIncrements) { + return appendCommand(commandObjects.topkIncrBy(key, itemIncrements)); + } + + @Override + public Response> topkQuery(String key, String... items) { + return appendCommand(commandObjects.topkQuery(key, items)); + } + + @Override + public Response> topkList(String key) { + return appendCommand(commandObjects.topkList(key)); + } + + @Override + public Response> topkListWithCount(String key) { + return appendCommand(commandObjects.topkListWithCount(key)); + } + + @Override + public Response> topkInfo(String key) { + return appendCommand(commandObjects.topkInfo(key)); + } + + @Override + public Response tdigestCreate(String key) { + return appendCommand(commandObjects.tdigestCreate(key)); + } + + @Override + public Response tdigestCreate(String key, int compression) { + return appendCommand(commandObjects.tdigestCreate(key, compression)); + } + + @Override + public Response tdigestReset(String key) { + return appendCommand(commandObjects.tdigestReset(key)); + } + + @Override + public Response tdigestMerge(String destinationKey, String... sourceKeys) { + return appendCommand(commandObjects.tdigestMerge(destinationKey, sourceKeys)); + } + + @Override + public Response tdigestMerge(TDigestMergeParams mergeParams, String destinationKey, String... sourceKeys) { + return appendCommand(commandObjects.tdigestMerge(mergeParams, destinationKey, sourceKeys)); + } + + @Override + public Response> tdigestInfo(String key) { + return appendCommand(commandObjects.tdigestInfo(key)); + } + + @Override + public Response tdigestAdd(String key, double... values) { + return appendCommand(commandObjects.tdigestAdd(key, values)); + } + + @Override + public Response> tdigestCDF(String key, double... values) { + return appendCommand(commandObjects.tdigestCDF(key, values)); + } + + @Override + public Response> tdigestQuantile(String key, double... quantiles) { + return appendCommand(commandObjects.tdigestQuantile(key, quantiles)); + } + + @Override + public Response tdigestMin(String key) { + return appendCommand(commandObjects.tdigestMin(key)); + } + + @Override + public Response tdigestMax(String key) { + return appendCommand(commandObjects.tdigestMax(key)); + } + + @Override + public Response tdigestTrimmedMean(String key, double lowCutQuantile, double highCutQuantile) { + return appendCommand(commandObjects.tdigestTrimmedMean(key, lowCutQuantile, highCutQuantile)); + } + + @Override + public Response> tdigestRank(String key, double... values) { + return appendCommand(commandObjects.tdigestRank(key, values)); + } + + @Override + public Response> tdigestRevRank(String key, double... values) { + return appendCommand(commandObjects.tdigestRevRank(key, values)); + } + + @Override + public Response> tdigestByRank(String key, long... ranks) { + return appendCommand(commandObjects.tdigestByRank(key, ranks)); + } + + @Override + public Response> tdigestByRevRank(String key, long... ranks) { + return appendCommand(commandObjects.tdigestByRevRank(key, ranks)); + } + // RedisBloom commands + + // RedisGraph commands + @Override + public Response graphQuery(String name, String query) { + return appendCommand(graphCommandObjects.graphQuery(name, query)); + } + + @Override + public Response graphReadonlyQuery(String name, String query) { + return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query)); + } + + @Override + public Response graphQuery(String name, String query, long timeout) { + return appendCommand(graphCommandObjects.graphQuery(name, query, timeout)); + } + + @Override + public Response graphReadonlyQuery(String name, String query, long timeout) { + return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query, timeout)); + } + + @Override + public Response graphQuery(String name, String query, Map params) { + return appendCommand(graphCommandObjects.graphQuery(name, query, params)); + } + + @Override + public Response graphReadonlyQuery(String name, String query, Map params) { + return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query, params)); + } + + @Override + public Response graphQuery(String name, String query, Map params, long timeout) { + return appendCommand(graphCommandObjects.graphQuery(name, query, params, timeout)); + } + + @Override + public Response graphReadonlyQuery(String name, String query, Map params, long timeout) { + return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query, params, timeout)); + } + + @Override + public Response graphDelete(String name) { + return appendCommand(graphCommandObjects.graphDelete(name)); + } + + @Override + public Response> graphProfile(String graphName, String query) { + return appendCommand(commandObjects.graphProfile(graphName, query)); + } + // RedisGraph commands + + public Response sendCommand(ProtocolCommand cmd, String... args) { + return sendCommand(new CommandArguments(cmd).addObjects((Object[]) args)); + } + + public Response sendCommand(ProtocolCommand cmd, byte[]... args) { + return sendCommand(new CommandArguments(cmd).addObjects((Object[]) args)); + } + + public Response sendCommand(CommandArguments args) { + return executeCommand(new CommandObject<>(args, BuilderFactory.RAW_OBJECT)); + } + + public Response executeCommand(CommandObject command) { + return appendCommand(command); + } + + public void setJsonObjectMapper(JsonObjectMapper jsonObjectMapper) { + this.commandObjects.setJsonObjectMapper(jsonObjectMapper); + } +} diff --git a/src/main/java/redis/clients/jedis/Protocol.java b/src/main/java/redis/clients/jedis/Protocol.java index 3f273877b5..531ee768c9 100644 --- a/src/main/java/redis/clients/jedis/Protocol.java +++ b/src/main/java/redis/clients/jedis/Protocol.java @@ -54,6 +54,7 @@ public final class Protocol { private static final String CLUSTERDOWN_PREFIX = "CLUSTERDOWN "; private static final String BUSY_PREFIX = "BUSY "; private static final String NOSCRIPT_PREFIX = "NOSCRIPT "; + private static final String NOAUTH_PREFIX = "NOAUTH"; private static final String WRONGPASS_PREFIX = "WRONGPASS"; private static final String NOPERM_PREFIX = "NOPERM"; @@ -97,9 +98,9 @@ private static void processError(final RedisInputStream is) { throw new JedisBusyException(message); } else if (message.startsWith(NOSCRIPT_PREFIX)) { throw new JedisNoScriptException(message); - } else if (message.startsWith(WRONGPASS_PREFIX)) { - throw new JedisAccessControlException(message); - } else if (message.startsWith(NOPERM_PREFIX)) { + } else if (message.startsWith(NOAUTH_PREFIX) + || message.startsWith(WRONGPASS_PREFIX) + || message.startsWith(NOPERM_PREFIX)) { throw new JedisAccessControlException(message); } throw new JedisDataException(message); @@ -272,7 +273,7 @@ public static enum Command implements ProtocolCommand { SSUBSCRIBE, SUNSUBSCRIBE, SPUBLISH, // <-- pub sub SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, PERSIST, ROLE, FAILOVER, SLOWLOG, OBJECT, CLIENT, TIME, SCAN, HSCAN, SSCAN, ZSCAN, WAIT, CLUSTER, ASKING, READONLY, READWRITE, SLAVEOF, REPLICAOF, COPY, - SENTINEL, MODULE, ACL, TOUCH, MEMORY, LOLWUT, COMMAND, LATENCY, WAITAOF; + SENTINEL, MODULE, ACL, TOUCH, MEMORY, LOLWUT, COMMAND, RESET, LATENCY, WAITAOF; private final byte[] raw; @@ -298,9 +299,9 @@ public static enum Keyword implements Rawable { REV, WITHCOORD, WITHDIST, WITHHASH, ANY, FROMMEMBER, FROMLONLAT, BYRADIUS, BYBOX, BYLEX, BYSCORE, STOREDIST, TO, FORCE, TIMEOUT, DB, UNLOAD, ABORT, IDX, MINMATCHLEN, WITHMATCHLEN, FULL, DELETE, LIBRARYNAME, WITHCODE, DESCRIPTION, GETKEYS, GETKEYSANDFLAGS, DOCS, FILTERBY, DUMP, - MODULE, ACLCAT, PATTERN, DOCTOR, USAGE, SAMPLES, PURGE, STATS, LOADEX, CONFIG, ARGS, RANK, + MODULE, ACLCAT, PATTERN, DOCTOR, LATEST, HISTORY, USAGE, SAMPLES, PURGE, STATS, LOADEX, CONFIG, ARGS, RANK, NOW, VERSION, ADDR, SKIPME, USER, LADDR, - CHANNELS, NUMPAT, NUMSUB, SHARDCHANNELS, SHARDNUMSUB; + CHANNELS, NUMPAT, NUMSUB, SHARDCHANNELS, SHARDNUMSUB, NOVALUES, MAXAGE; private final byte[] raw; @@ -357,7 +358,7 @@ public static enum ClusterKeyword implements Rawable { MEET, RESET, INFO, FAILOVER, SLOTS, NODES, REPLICAS, SLAVES, MYID, ADDSLOTS, DELSLOTS, GETKEYSINSLOT, SETSLOT, NODE, MIGRATING, IMPORTING, STABLE, FORGET, FLUSHSLOTS, KEYSLOT, COUNTKEYSINSLOT, SAVECONFIG, REPLICATE, LINKS, ADDSLOTSRANGE, DELSLOTSRANGE, BUMPEPOCH, - MYSHARDID; + MYSHARDID, SHARDS; private final byte[] raw; diff --git a/src/main/java/redis/clients/jedis/ReliableTransaction.java b/src/main/java/redis/clients/jedis/ReliableTransaction.java index a0db77a068..c750bdb9d9 100644 --- a/src/main/java/redis/clients/jedis/ReliableTransaction.java +++ b/src/main/java/redis/clients/jedis/ReliableTransaction.java @@ -1,7 +1,20 @@ package redis.clients.jedis; +import static redis.clients.jedis.Protocol.Command.DISCARD; +import static redis.clients.jedis.Protocol.Command.EXEC; +import static redis.clients.jedis.Protocol.Command.MULTI; +import static redis.clients.jedis.Protocol.Command.UNWATCH; +import static redis.clients.jedis.Protocol.Command.WATCH; + +import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; +import java.util.Queue; + +import redis.clients.jedis.exceptions.JedisConnectionException; +import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisException; +import redis.clients.jedis.graph.GraphCommandObjects; /** * ReliableTransaction is a transaction where commands are immediately sent to Redis server and the @@ -11,6 +24,14 @@ public class ReliableTransaction extends TransactionBase { private static final String QUEUED_STR = "QUEUED"; + private final Queue> pipelinedResponses = new LinkedList<>(); + protected final Connection connection; + private final boolean closeConnection; + + private boolean broken = false; + private boolean inWatch = false; + private boolean inMulti = false; + /** * Creates a new transaction. * @@ -18,7 +39,7 @@ public class ReliableTransaction extends TransactionBase { * @param connection connection */ public ReliableTransaction(Connection connection) { - super(connection); + this(connection, true); } /** @@ -31,7 +52,7 @@ public ReliableTransaction(Connection connection) { * @param doMulti {@code false} should be set to enable manual WATCH, UNWATCH and MULTI */ public ReliableTransaction(Connection connection, boolean doMulti) { - super(connection, doMulti); + this(connection, doMulti, false); } /** @@ -45,41 +66,141 @@ public ReliableTransaction(Connection connection, boolean doMulti) { * @param closeConnection should the 'connection' be closed when 'close()' is called? */ public ReliableTransaction(Connection connection, boolean doMulti, boolean closeConnection) { - super(connection, doMulti, closeConnection); + this.connection = connection; + this.closeConnection = closeConnection; + setGraphCommands(new GraphCommandObjects(this.connection)); + if (doMulti) multi(); } @Override - protected final void processMultiResponse() { + public final void multi() { + connection.sendCommand(MULTI); String status = connection.getStatusCodeReply(); if (!"OK".equals(status)) { throw new JedisException("MULTI command failed. Received response: " + status); } + inMulti = true; + } + + @Override + public String watch(final String... keys) { + connection.sendCommand(WATCH, keys); + String status = connection.getStatusCodeReply(); + inWatch = true; + return status; } @Override - protected final void processAppendStatus() { + public String watch(final byte[]... keys) { + connection.sendCommand(WATCH, keys); + String status = connection.getStatusCodeReply(); + inWatch = true; + return status; + } + + @Override + public String unwatch() { + connection.sendCommand(UNWATCH); + String status = connection.getStatusCodeReply(); + inWatch = false; + return status; + } + + @Override + protected final Response appendCommand(CommandObject commandObject) { + connection.sendCommand(commandObject.getArguments()); String status = connection.getStatusCodeReply(); if (!QUEUED_STR.equals(status)) { throw new JedisException(status); } + Response response = new Response<>(commandObject.getBuilder()); + pipelinedResponses.add(response); + return response; } @Override - protected final void processPipelinedResponses(int pipelineLength) { - // do nothing + public final void close() { + try { + clear(); + } finally { + if (closeConnection) { + connection.close(); + } + } + } + + @Deprecated // TODO: private + public final void clear() { + if (broken) { + return; + } + if (inMulti) { + discard(); + } else if (inWatch) { + unwatch(); + } } @Override - public final List exec() { - return super.exec(); + public List exec() { + if (!inMulti) { + throw new IllegalStateException("EXEC without MULTI"); + } + + try { + // processPipelinedResponses(pipelinedResponses.size()); + // do nothing + connection.sendCommand(EXEC); + + List unformatted = connection.getObjectMultiBulkReply(); + if (unformatted == null) { + pipelinedResponses.clear(); + return null; + } + + List formatted = new ArrayList<>(unformatted.size()); + for (Object o : unformatted) { + try { + Response response = pipelinedResponses.poll(); + response.set(o); + formatted.add(response.get()); + } catch (JedisDataException e) { + formatted.add(e); + } + } + return formatted; + } catch (JedisConnectionException jce) { + broken = true; + throw jce; + } finally { + inMulti = false; + inWatch = false; + pipelinedResponses.clear(); + } } @Override - public final String discard() { - String status = super.discard(); - if (!"OK".equals(status)) { - throw new JedisException("DISCARD command failed. Received response: " + status); + public String discard() { + if (!inMulti) { + throw new IllegalStateException("DISCARD without MULTI"); + } + + try { + // processPipelinedResponses(pipelinedResponses.size()); + // do nothing + connection.sendCommand(DISCARD); + String status = connection.getStatusCodeReply(); + if (!"OK".equals(status)) { + throw new JedisException("DISCARD command failed. Received response: " + status); + } + return status; + } catch (JedisConnectionException jce) { + broken = true; + throw jce; + } finally { + inMulti = false; + inWatch = false; + pipelinedResponses.clear(); } - return status; } } diff --git a/src/main/java/redis/clients/jedis/Transaction.java b/src/main/java/redis/clients/jedis/Transaction.java index a799ae3da9..0dccd655a0 100644 --- a/src/main/java/redis/clients/jedis/Transaction.java +++ b/src/main/java/redis/clients/jedis/Transaction.java @@ -1,18 +1,40 @@ package redis.clients.jedis; +import static redis.clients.jedis.Protocol.Command.DISCARD; +import static redis.clients.jedis.Protocol.Command.EXEC; +import static redis.clients.jedis.Protocol.Command.MULTI; +import static redis.clients.jedis.Protocol.Command.UNWATCH; +import static redis.clients.jedis.Protocol.Command.WATCH; + +import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; +import java.util.Queue; + +import redis.clients.jedis.exceptions.JedisConnectionException; +import redis.clients.jedis.exceptions.JedisDataException; +import redis.clients.jedis.graph.GraphCommandObjects; /** * A pipeline based transaction. */ public class Transaction extends TransactionBase { - private final Jedis jedis; + private final Queue> pipelinedResponses = new LinkedList<>(); + + private Jedis jedis = null; + + protected final Connection connection; + private final boolean closeConnection; + + private boolean broken = false; + private boolean inWatch = false; + private boolean inMulti = false; // Legacy - to support Jedis.multi() // TODO: Should be package private ?? public Transaction(Jedis jedis) { - super(jedis.getConnection()); + this(jedis.getConnection()); this.jedis = jedis; } @@ -24,8 +46,7 @@ public Transaction(Jedis jedis) { * @param connection connection */ public Transaction(Connection connection) { - super(connection); - this.jedis = null; + this(connection, true); } /** @@ -38,8 +59,7 @@ public Transaction(Connection connection) { * @param doMulti {@code false} should be set to enable manual WATCH, UNWATCH and MULTI */ public Transaction(Connection connection, boolean doMulti) { - super(connection, doMulti); - this.jedis = null; + this(connection, doMulti, false); } /** @@ -53,49 +73,142 @@ public Transaction(Connection connection, boolean doMulti) { * @param closeConnection should the 'connection' be closed when 'close()' is called? */ public Transaction(Connection connection, boolean doMulti, boolean closeConnection) { - super(connection, doMulti, closeConnection); - this.jedis = null; + this.connection = connection; + this.closeConnection = closeConnection; + setGraphCommands(new GraphCommandObjects(this.connection)); + if (doMulti) multi(); } @Override - protected final void processMultiResponse() { - // do nothing + public final void multi() { + connection.sendCommand(MULTI); + // processMultiResponse(); // do nothing + inMulti = true; } @Override - protected final void processAppendStatus() { - // do nothing + public String watch(final String... keys) { + connection.sendCommand(WATCH, keys); + String status = connection.getStatusCodeReply(); + inWatch = true; + return status; } @Override - protected final void processPipelinedResponses(int pipelineLength) { - // ignore QUEUED or ERROR - connection.getMany(1 + pipelineLength); + public String watch(final byte[]... keys) { + connection.sendCommand(WATCH, keys); + String status = connection.getStatusCodeReply(); + inWatch = true; + return status; } @Override - public final List exec() { - List ret; + public String unwatch() { + connection.sendCommand(UNWATCH); + String status = connection.getStatusCodeReply(); + inWatch = false; + return status; + } + + @Override + protected final Response appendCommand(CommandObject commandObject) { + connection.sendCommand(commandObject.getArguments()); + // processAppendStatus(); // do nothing + Response response = new Response<>(commandObject.getBuilder()); + pipelinedResponses.add(response); + return response; + } + + @Override + public final void close() { try { - ret = super.exec(); + clear(); } finally { + if (closeConnection) { + connection.close(); + } + } + } + + @Deprecated // TODO: private + public final void clear() { + if (broken) { + return; + } + if (inMulti) { + discard(); + } else if (inWatch) { + unwatch(); + } + } + + @Override + public List exec() { + if (!inMulti) { + throw new IllegalStateException("EXEC without MULTI"); + } + + try { + // ignore QUEUED (or ERROR) + // processPipelinedResponses(pipelinedResponses.size()); + connection.getMany(1 + pipelinedResponses.size()); + + connection.sendCommand(EXEC); + + List unformatted = connection.getObjectMultiBulkReply(); + if (unformatted == null) { + pipelinedResponses.clear(); + return null; + } + + List formatted = new ArrayList<>(unformatted.size()); + for (Object o : unformatted) { + try { + Response response = pipelinedResponses.poll(); + response.set(o); + formatted.add(response.get()); + } catch (JedisDataException e) { + formatted.add(e); + } + } + return formatted; + } catch (JedisConnectionException jce) { + broken = true; + throw jce; + } finally { + inMulti = false; + inWatch = false; + pipelinedResponses.clear(); if (jedis != null) { jedis.resetState(); } } - return ret; } @Override - public final String discard() { - String ret; + public String discard() { + if (!inMulti) { + throw new IllegalStateException("DISCARD without MULTI"); + } + try { - ret = super.discard(); + // ignore QUEUED (or ERROR) + // processPipelinedResponses(pipelinedResponses.size()); + connection.getMany(1 + pipelinedResponses.size()); + + connection.sendCommand(DISCARD); + + return connection.getStatusCodeReply(); + } catch (JedisConnectionException jce) { + broken = true; + throw jce; } finally { + inMulti = false; + inWatch = false; + pipelinedResponses.clear(); if (jedis != null) { jedis.resetState(); } } - return ret; } } diff --git a/src/main/java/redis/clients/jedis/TransactionBase.java b/src/main/java/redis/clients/jedis/TransactionBase.java index 2c02316f59..efdf332700 100644 --- a/src/main/java/redis/clients/jedis/TransactionBase.java +++ b/src/main/java/redis/clients/jedis/TransactionBase.java @@ -1,4397 +1,16 @@ package redis.clients.jedis; -import static redis.clients.jedis.Protocol.Command.DISCARD; -import static redis.clients.jedis.Protocol.Command.EXEC; -import static redis.clients.jedis.Protocol.Command.MULTI; -import static redis.clients.jedis.Protocol.Command.UNWATCH; -import static redis.clients.jedis.Protocol.Command.WATCH; +/** + * @deprecated Use {@link AbstractTransaction}. + */ +@Deprecated +public abstract class TransactionBase extends AbstractTransaction { -import java.io.Closeable; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Set; -import org.json.JSONArray; - -import redis.clients.jedis.args.*; -import redis.clients.jedis.bloom.*; -import redis.clients.jedis.commands.PipelineBinaryCommands; -import redis.clients.jedis.commands.PipelineCommands; -import redis.clients.jedis.commands.ProtocolCommand; -import redis.clients.jedis.commands.RedisModulePipelineCommands; -import redis.clients.jedis.exceptions.JedisConnectionException; -import redis.clients.jedis.exceptions.JedisDataException; -import redis.clients.jedis.graph.GraphCommandObjects; -import redis.clients.jedis.graph.ResultSet; -import redis.clients.jedis.json.JsonSetParams; -import redis.clients.jedis.json.Path; -import redis.clients.jedis.json.Path2; -import redis.clients.jedis.json.JsonObjectMapper; -import redis.clients.jedis.params.*; -import redis.clients.jedis.resps.*; -import redis.clients.jedis.search.*; -import redis.clients.jedis.search.aggr.AggregationBuilder; -import redis.clients.jedis.search.aggr.AggregationResult; -import redis.clients.jedis.search.schemafields.SchemaField; -import redis.clients.jedis.timeseries.*; -import redis.clients.jedis.util.KeyValue; - -public abstract class TransactionBase implements PipelineCommands, PipelineBinaryCommands, - RedisModulePipelineCommands, Closeable { - - private final Queue> pipelinedResponses = new LinkedList<>(); - protected final Connection connection; - private final boolean closeConnection; - private final CommandObjects commandObjects; - private final GraphCommandObjects graphCommandObjects; - - private boolean broken = false; - private boolean inWatch = false; - private boolean inMulti = false; - - /** - * Creates a new transaction. - * - * A MULTI command will be added to be sent to server. WATCH/UNWATCH/MULTI commands must not be - * called with this object. - * @param connection connection - */ - public TransactionBase(Connection connection) { - this(connection, true); - } - - /** - * Creates a new transaction. - * - * A user wanting to WATCH/UNWATCH keys followed by a call to MULTI ({@link #multi()}) it should - * be {@code doMulti=false}. - * - * @param connection connection - * @param doMulti {@code false} should be set to enable manual WATCH, UNWATCH and MULTI - */ - public TransactionBase(Connection connection, boolean doMulti) { - this(connection, doMulti, false); - } - - /** - * Creates a new transaction. - * - * A user wanting to WATCH/UNWATCH keys followed by a call to MULTI ({@link #multi()}) it should - * be {@code doMulti=false}. - * - * @param connection connection - * @param doMulti {@code false} should be set to enable manual WATCH, UNWATCH and MULTI - * @param closeConnection should the 'connection' be closed when 'close()' is called? - */ - public TransactionBase(Connection connection, boolean doMulti, boolean closeConnection) { - this.connection = connection; - this.closeConnection = closeConnection; - this.commandObjects = new CommandObjects(); - this.graphCommandObjects = new GraphCommandObjects(this.connection); - if (doMulti) multi(); - } - - public final void multi() { - connection.sendCommand(MULTI); - processMultiResponse(); - inMulti = true; - } - - public String watch(final String... keys) { - connection.sendCommand(WATCH, keys); - String status = connection.getStatusCodeReply(); - inWatch = true; - return status; - } - - public String watch(final byte[]... keys) { - connection.sendCommand(WATCH, keys); - String status = connection.getStatusCodeReply(); - inWatch = true; - return status; - } - - public String unwatch() { - connection.sendCommand(UNWATCH); - String status = connection.getStatusCodeReply(); - inWatch = false; - return status; - } - - protected abstract void processMultiResponse(); - - protected abstract void processAppendStatus(); - - protected final Response appendCommand(CommandObject commandObject) { - connection.sendCommand(commandObject.getArguments()); - processAppendStatus(); - Response response = new Response<>(commandObject.getBuilder()); - pipelinedResponses.add(response); - return response; - } - - @Override - public final void close() { - try { - clear(); - } finally { - if (closeConnection) { - connection.close(); - } - } - } - - public final void clear() { - if (broken) { - return; - } - if (inMulti) { - discard(); - } else if (inWatch) { - unwatch(); - } - } - - protected abstract void processPipelinedResponses(int pipelineLength); - - public List exec() { - if (!inMulti) { - throw new IllegalStateException("EXEC without MULTI"); - } - - try { - processPipelinedResponses(pipelinedResponses.size()); - connection.sendCommand(EXEC); - - List unformatted = connection.getObjectMultiBulkReply(); - if (unformatted == null) { - pipelinedResponses.clear(); - return null; - } - - List formatted = new ArrayList<>(unformatted.size()); - for (Object o : unformatted) { - try { - Response response = pipelinedResponses.poll(); - response.set(o); - formatted.add(response.get()); - } catch (JedisDataException e) { - formatted.add(e); - } - } - return formatted; - } catch (JedisConnectionException jce) { - broken = true; - throw jce; - } finally { - inMulti = false; - inWatch = false; - pipelinedResponses.clear(); - } - } - - public String discard() { - if (!inMulti) { - throw new IllegalStateException("DISCARD without MULTI"); - } - - try { - processPipelinedResponses(pipelinedResponses.size()); - connection.sendCommand(DISCARD); - return connection.getStatusCodeReply(); - } catch (JedisConnectionException jce) { - broken = true; - throw jce; - } finally { - inMulti = false; - inWatch = false; - pipelinedResponses.clear(); - } - } - - @Override - public Response exists(String key) { - return appendCommand(commandObjects.exists(key)); - } - - @Override - public Response exists(String... keys) { - return appendCommand(commandObjects.exists(keys)); - } - - @Override - public Response persist(String key) { - return appendCommand(commandObjects.persist(key)); - } - - @Override - public Response type(String key) { - return appendCommand(commandObjects.type(key)); - } - - @Override - public Response dump(String key) { - return appendCommand(commandObjects.dump(key)); - } - - @Override - public Response restore(String key, long ttl, byte[] serializedValue) { - return appendCommand(commandObjects.restore(key, ttl, serializedValue)); - } - - @Override - public Response restore(String key, long ttl, byte[] serializedValue, RestoreParams params) { - return appendCommand(commandObjects.restore(key, ttl, serializedValue, params)); - } - - @Override - public Response expire(String key, long seconds) { - return appendCommand(commandObjects.expire(key, seconds)); - } - - @Override - public Response expire(String key, long seconds, ExpiryOption expiryOption) { - return appendCommand(commandObjects.expire(key, seconds, expiryOption)); - } - - @Override - public Response pexpire(String key, long milliseconds) { - return appendCommand(commandObjects.pexpire(key, milliseconds)); - } - - @Override - public Response pexpire(String key, long milliseconds, ExpiryOption expiryOption) { - return appendCommand(commandObjects.pexpire(key, milliseconds, expiryOption)); - } - - @Override - public Response expireTime(String key) { - return appendCommand(commandObjects.expireTime(key)); - } - - @Override - public Response pexpireTime(String key) { - return appendCommand(commandObjects.pexpireTime(key)); - } - - @Override - public Response expireAt(String key, long unixTime) { - return appendCommand(commandObjects.expireAt(key, unixTime)); - } - - @Override - public Response expireAt(String key, long unixTime, ExpiryOption expiryOption) { - return appendCommand(commandObjects.expireAt(key, unixTime, expiryOption)); - } - - @Override - public Response pexpireAt(String key, long millisecondsTimestamp) { - return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp)); - } - - @Override - public Response pexpireAt(String key, long millisecondsTimestamp, ExpiryOption expiryOption) { - return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp, expiryOption)); - } - - @Override - public Response ttl(String key) { - return appendCommand(commandObjects.ttl(key)); - } - - @Override - public Response pttl(String key) { - return appendCommand(commandObjects.pttl(key)); - } - - @Override - public Response touch(String key) { - return appendCommand(commandObjects.touch(key)); - } - - @Override - public Response touch(String... keys) { - return appendCommand(commandObjects.touch(keys)); - } - - @Override - public Response> sort(String key) { - return appendCommand(commandObjects.sort(key)); - } - - @Override - public Response sort(String key, String dstKey) { - return appendCommand(commandObjects.sort(key, dstKey)); - } - - @Override - public Response> sort(String key, SortingParams sortingParams) { - return appendCommand(commandObjects.sort(key, sortingParams)); - } - - @Override - public Response sort(String key, SortingParams sortingParams, String dstKey) { - return appendCommand(commandObjects.sort(key, sortingParams, dstKey)); - } - - @Override - public Response> sortReadonly(String key, SortingParams sortingParams) { - return appendCommand(commandObjects.sortReadonly(key, sortingParams)); - } - - @Override - public Response del(String key) { - return appendCommand(commandObjects.del(key)); - } - - @Override - public Response del(String... keys) { - return appendCommand(commandObjects.del(keys)); - } - - @Override - public Response unlink(String key) { - return appendCommand(commandObjects.unlink(key)); - } - - @Override - public Response unlink(String... keys) { - return appendCommand(commandObjects.unlink(keys)); - } - - @Override - public Response copy(String srcKey, String dstKey, boolean replace) { - return appendCommand(commandObjects.copy(srcKey, dstKey, replace)); - } - - @Override - public Response rename(String oldkey, String newkey) { - return appendCommand(commandObjects.rename(oldkey, newkey)); - } - - @Override - public Response renamenx(String oldkey, String newkey) { - return appendCommand(commandObjects.renamenx(oldkey, newkey)); - } - - @Override - public Response memoryUsage(String key) { - return appendCommand(commandObjects.memoryUsage(key)); - } - - @Override - public Response memoryUsage(String key, int samples) { - return appendCommand(commandObjects.memoryUsage(key, samples)); - } - - @Override - public Response objectRefcount(String key) { - return appendCommand(commandObjects.objectRefcount(key)); - } - - @Override - public Response objectEncoding(String key) { - return appendCommand(commandObjects.objectEncoding(key)); - } - - @Override - public Response objectIdletime(String key) { - return appendCommand(commandObjects.objectIdletime(key)); - } - - @Override - public Response objectFreq(String key) { - return appendCommand(commandObjects.objectFreq(key)); - } - - @Override - public Response migrate(String host, int port, String key, int timeout) { - return appendCommand(commandObjects.migrate(host, port, key, timeout)); - } - - @Override - public Response migrate(String host, int port, int timeout, MigrateParams params, String... keys) { - return appendCommand(commandObjects.migrate(host, port, timeout, params, keys)); - } - - @Override - public Response> keys(String pattern) { - return appendCommand(commandObjects.keys(pattern)); - } - - @Override - public Response> scan(String cursor) { - return appendCommand(commandObjects.scan(cursor)); - } - - @Override - public Response> scan(String cursor, ScanParams params) { - return appendCommand(commandObjects.scan(cursor, params)); - } - - @Override - public Response> scan(String cursor, ScanParams params, String type) { - return appendCommand(commandObjects.scan(cursor, params, type)); - } - - @Override - public Response randomKey() { - return appendCommand(commandObjects.randomKey()); - } - - @Override - public Response get(String key) { - return appendCommand(commandObjects.get(key)); - } - - @Override - public Response setGet(String key, String value, SetParams params) { - return appendCommand(commandObjects.setGet(key, value, params)); - } - - @Override - public Response getDel(String key) { - return appendCommand(commandObjects.getDel(key)); - } - - @Override - public Response getEx(String key, GetExParams params) { - return appendCommand(commandObjects.getEx(key, params)); - } - - @Override - public Response setbit(String key, long offset, boolean value) { - return appendCommand(commandObjects.setbit(key, offset, value)); - } - - @Override - public Response getbit(String key, long offset) { - return appendCommand(commandObjects.getbit(key, offset)); - } - - @Override - public Response setrange(String key, long offset, String value) { - return appendCommand(commandObjects.setrange(key, offset, value)); - } - - @Override - public Response getrange(String key, long startOffset, long endOffset) { - return appendCommand(commandObjects.getrange(key, startOffset, endOffset)); - } - - @Override - public Response getSet(String key, String value) { - return appendCommand(commandObjects.getSet(key, value)); - } - - @Override - public Response setnx(String key, String value) { - return appendCommand(commandObjects.setnx(key, value)); - } - - @Override - public Response setex(String key, long seconds, String value) { - return appendCommand(commandObjects.setex(key, seconds, value)); - } - - @Override - public Response psetex(String key, long milliseconds, String value) { - return appendCommand(commandObjects.psetex(key, milliseconds, value)); - } - - @Override - public Response> mget(String... keys) { - return appendCommand(commandObjects.mget(keys)); - } - - @Override - public Response mset(String... keysvalues) { - return appendCommand(commandObjects.mset(keysvalues)); - } - - @Override - public Response msetnx(String... keysvalues) { - return appendCommand(commandObjects.msetnx(keysvalues)); - } - - @Override - public Response incr(String key) { - return appendCommand(commandObjects.incr(key)); - } - - @Override - public Response incrBy(String key, long increment) { - return appendCommand(commandObjects.incrBy(key, increment)); - } - - @Override - public Response incrByFloat(String key, double increment) { - return appendCommand(commandObjects.incrByFloat(key, increment)); - } - - @Override - public Response decr(String key) { - return appendCommand(commandObjects.decr(key)); - } - - @Override - public Response decrBy(String key, long decrement) { - return appendCommand(commandObjects.decrBy(key, decrement)); - } - - @Override - public Response append(String key, String value) { - return appendCommand(commandObjects.append(key, value)); - } - - @Override - public Response substr(String key, int start, int end) { - return appendCommand(commandObjects.substr(key, start, end)); - } - - @Override - public Response strlen(String key) { - return appendCommand(commandObjects.strlen(key)); - } - - @Override - public Response bitcount(String key) { - return appendCommand(commandObjects.bitcount(key)); - } - - @Override - public Response bitcount(String key, long start, long end) { - return appendCommand(commandObjects.bitcount(key, start, end)); - } - - @Override - public Response bitcount(String key, long start, long end, BitCountOption option) { - return appendCommand(commandObjects.bitcount(key, start, end, option)); - } - - @Override - public Response bitpos(String key, boolean value) { - return appendCommand(commandObjects.bitpos(key, value)); - } - - @Override - public Response bitpos(String key, boolean value, BitPosParams params) { - return appendCommand(commandObjects.bitpos(key, value, params)); - } - - @Override - public Response> bitfield(String key, String... arguments) { - return appendCommand(commandObjects.bitfield(key, arguments)); - } - - @Override - public Response> bitfieldReadonly(String key, String... arguments) { - return appendCommand(commandObjects.bitfieldReadonly(key, arguments)); - } - - @Override - public Response bitop(BitOP op, String destKey, String... srcKeys) { - return appendCommand(commandObjects.bitop(op, destKey, srcKeys)); - } - - @Override - public Response lcs(String keyA, String keyB, LCSParams params) { - return appendCommand(commandObjects.lcs(keyA, keyB, params)); - } - - @Override - public Response set(String key, String value) { - return appendCommand(commandObjects.set(key, value)); - } - - @Override - public Response set(String key, String value, SetParams params) { - return appendCommand(commandObjects.set(key, value, params)); - } - - @Override - public Response rpush(String key, String... string) { - return appendCommand(commandObjects.rpush(key, string)); - - } - - @Override - public Response lpush(String key, String... string) { - return appendCommand(commandObjects.lpush(key, string)); - } - - @Override - public Response llen(String key) { - return appendCommand(commandObjects.llen(key)); - } - - @Override - public Response> lrange(String key, long start, long stop) { - return appendCommand(commandObjects.lrange(key, start, stop)); - } - - @Override - public Response ltrim(String key, long start, long stop) { - return appendCommand(commandObjects.ltrim(key, start, stop)); - } - - @Override - public Response lindex(String key, long index) { - return appendCommand(commandObjects.lindex(key, index)); - } - - @Override - public Response lset(String key, long index, String value) { - return appendCommand(commandObjects.lset(key, index, value)); - } - - @Override - public Response lrem(String key, long count, String value) { - return appendCommand(commandObjects.lrem(key, count, value)); - } - - @Override - public Response lpop(String key) { - return appendCommand(commandObjects.lpop(key)); - } - - @Override - public Response> lpop(String key, int count) { - return appendCommand(commandObjects.lpop(key, count)); - } - - @Override - public Response lpos(String key, String element) { - return appendCommand(commandObjects.lpos(key, element)); - } - - @Override - public Response lpos(String key, String element, LPosParams params) { - return appendCommand(commandObjects.lpos(key, element, params)); - } - - @Override - public Response> lpos(String key, String element, LPosParams params, long count) { - return appendCommand(commandObjects.lpos(key, element, params, count)); - } - - @Override - public Response rpop(String key) { - return appendCommand(commandObjects.rpop(key)); - } - - @Override - public Response> rpop(String key, int count) { - return appendCommand(commandObjects.rpop(key, count)); - } - - @Override - public Response linsert(String key, ListPosition where, String pivot, String value) { - return appendCommand(commandObjects.linsert(key, where, pivot, value)); - } - - @Override - public Response lpushx(String key, String... strings) { - return appendCommand(commandObjects.lpushx(key, strings)); - } - - @Override - public Response rpushx(String key, String... strings) { - return appendCommand(commandObjects.rpushx(key, strings)); - } - - @Override - public Response> blpop(int timeout, String key) { - return appendCommand(commandObjects.blpop(timeout, key)); - } - - @Override - public Response> blpop(double timeout, String key) { - return appendCommand(commandObjects.blpop(timeout, key)); - } - - @Override - public Response> brpop(int timeout, String key) { - return appendCommand(commandObjects.brpop(timeout, key)); - } - - @Override - public Response> brpop(double timeout, String key) { - return appendCommand(commandObjects.brpop(timeout, key)); - } - - @Override - public Response> blpop(int timeout, String... keys) { - return appendCommand(commandObjects.blpop(timeout, keys)); - } - - @Override - public Response> blpop(double timeout, String... keys) { - return appendCommand(commandObjects.blpop(timeout, keys)); - } - - @Override - public Response> brpop(int timeout, String... keys) { - return appendCommand(commandObjects.brpop(timeout, keys)); - } - - @Override - public Response> brpop(double timeout, String... keys) { - return appendCommand(commandObjects.brpop(timeout, keys)); - } - - @Override - public Response rpoplpush(String srcKey, String dstKey) { - return appendCommand(commandObjects.rpoplpush(srcKey, dstKey)); - } - - @Override - public Response brpoplpush(String source, String destination, int timeout) { - return appendCommand(commandObjects.brpoplpush(source, destination, timeout)); - } - - @Override - public Response lmove(String srcKey, String dstKey, ListDirection from, ListDirection to) { - return appendCommand(commandObjects.lmove(srcKey, dstKey, from, to)); - } - - @Override - public Response blmove(String srcKey, String dstKey, ListDirection from, ListDirection to, double timeout) { - return appendCommand(commandObjects.blmove(srcKey, dstKey, from, to, timeout)); - } - - @Override - public Response>> lmpop(ListDirection direction, String... keys) { - return appendCommand(commandObjects.lmpop(direction, keys)); - } - - @Override - public Response>> lmpop(ListDirection direction, int count, String... keys) { - return appendCommand(commandObjects.lmpop(direction, count, keys)); - } - - @Override - public Response>> blmpop(double timeout, ListDirection direction, String... keys) { - return appendCommand(commandObjects.blmpop(timeout, direction, keys)); - } - - @Override - public Response>> blmpop(double timeout, ListDirection direction, int count, String... keys) { - return appendCommand(commandObjects.blmpop(timeout, direction, count, keys)); - } - - @Override - public Response hset(String key, String field, String value) { - return appendCommand(commandObjects.hset(key, field, value)); - } - - @Override - public Response hset(String key, Map hash) { - return appendCommand(commandObjects.hset(key, hash)); - } - - @Override - public Response hget(String key, String field) { - return appendCommand(commandObjects.hget(key, field)); - } - - @Override - public Response hsetnx(String key, String field, String value) { - return appendCommand(commandObjects.hsetnx(key, field, value)); - } - - @Override - public Response hmset(String key, Map hash) { - return appendCommand(commandObjects.hmset(key, hash)); - } - - @Override - public Response> hmget(String key, String... fields) { - return appendCommand(commandObjects.hmget(key, fields)); - } - - @Override - public Response hincrBy(String key, String field, long value) { - return appendCommand(commandObjects.hincrBy(key, field, value)); - } - - @Override - public Response hincrByFloat(String key, String field, double value) { - return appendCommand(commandObjects.hincrByFloat(key, field, value)); - } - - @Override - public Response hexists(String key, String field) { - return appendCommand(commandObjects.hexists(key, field)); - } - - @Override - public Response hdel(String key, String... field) { - return appendCommand(commandObjects.hdel(key, field)); - } - - @Override - public Response hlen(String key) { - return appendCommand(commandObjects.hlen(key)); - } - - @Override - public Response> hkeys(String key) { - return appendCommand(commandObjects.hkeys(key)); - } - - @Override - public Response> hvals(String key) { - return appendCommand(commandObjects.hvals(key)); - } - - @Override - public Response> hgetAll(String key) { - return appendCommand(commandObjects.hgetAll(key)); - } - - @Override - public Response hrandfield(String key) { - return appendCommand(commandObjects.hrandfield(key)); - } - - @Override - public Response> hrandfield(String key, long count) { - return appendCommand(commandObjects.hrandfield(key, count)); - } - - @Override - public Response>> hrandfieldWithValues(String key, long count) { - return appendCommand(commandObjects.hrandfieldWithValues(key, count)); - } - - @Override - public Response>> hscan(String key, String cursor, ScanParams params) { - return appendCommand(commandObjects.hscan(key, cursor, params)); - } - - @Override - public Response hstrlen(String key, String field) { - return appendCommand(commandObjects.hstrlen(key, field)); - } - - @Override - public Response sadd(String key, String... members) { - return appendCommand(commandObjects.sadd(key, members)); - } - - @Override - public Response> smembers(String key) { - return appendCommand(commandObjects.smembers(key)); - } - - @Override - public Response srem(String key, String... members) { - return appendCommand(commandObjects.srem(key, members)); - } - - @Override - public Response spop(String key) { - return appendCommand(commandObjects.spop(key)); - } - - @Override - public Response> spop(String key, long count) { - return appendCommand(commandObjects.spop(key, count)); - } - - @Override - public Response scard(String key) { - return appendCommand(commandObjects.scard(key)); - } - - @Override - public Response sismember(String key, String member) { - return appendCommand(commandObjects.sismember(key, member)); - } - - @Override - public Response> smismember(String key, String... members) { - return appendCommand(commandObjects.smismember(key, members)); - } - - @Override - public Response srandmember(String key) { - return appendCommand(commandObjects.srandmember(key)); - } - - @Override - public Response> srandmember(String key, int count) { - return appendCommand(commandObjects.srandmember(key, count)); - } - - @Override - public Response> sscan(String key, String cursor, ScanParams params) { - return appendCommand(commandObjects.sscan(key, cursor, params)); - } - - @Override - public Response> sdiff(String... keys) { - return appendCommand(commandObjects.sdiff(keys)); - } - - @Override - public Response sdiffStore(String dstKey, String... keys) { - return appendCommand(commandObjects.sdiffstore(dstKey, keys)); - } - - @Override - public Response> sinter(String... keys) { - return appendCommand(commandObjects.sinter(keys)); - } - - @Override - public Response sinterstore(String dstKey, String... keys) { - return appendCommand(commandObjects.sinterstore(dstKey, keys)); - } - - @Override - public Response sintercard(String... keys) { - return appendCommand(commandObjects.sintercard(keys)); - } - - @Override - public Response sintercard(int limit, String... keys) { - return appendCommand(commandObjects.sintercard(limit, keys)); - } - - @Override - public Response> sunion(String... keys) { - return appendCommand(commandObjects.sunion(keys)); - } - - @Override - public Response sunionstore(String dstKey, String... keys) { - return appendCommand(commandObjects.sunionstore(dstKey, keys)); - } - - @Override - public Response smove(String srcKey, String dstKey, String member) { - return appendCommand(commandObjects.smove(srcKey, dstKey, member)); - } - - @Override - public Response zadd(String key, double score, String member) { - return appendCommand(commandObjects.zadd(key, score, member)); - } - - @Override - public Response zadd(String key, double score, String member, ZAddParams params) { - return appendCommand(commandObjects.zadd(key, score, member, params)); - } - - @Override - public Response zadd(String key, Map scoreMembers) { - return appendCommand(commandObjects.zadd(key, scoreMembers)); - } - - @Override - public Response zadd(String key, Map scoreMembers, ZAddParams params) { - return appendCommand(commandObjects.zadd(key, scoreMembers, params)); - } - - @Override - public Response zaddIncr(String key, double score, String member, ZAddParams params) { - return appendCommand(commandObjects.zaddIncr(key, score, member, params)); - } - - @Override - public Response zrem(String key, String... members) { - return appendCommand(commandObjects.zrem(key, members)); - } - - @Override - public Response zincrby(String key, double increment, String member) { - return appendCommand(commandObjects.zincrby(key, increment, member)); - } - - @Override - public Response zincrby(String key, double increment, String member, ZIncrByParams params) { - return appendCommand(commandObjects.zincrby(key, increment, member, params)); - } - - @Override - public Response zrank(String key, String member) { - return appendCommand(commandObjects.zrank(key, member)); - } - - @Override - public Response zrevrank(String key, String member) { - return appendCommand(commandObjects.zrevrank(key, member)); - } - - @Override - public Response> zrankWithScore(String key, String member) { - return appendCommand(commandObjects.zrankWithScore(key, member)); - } - - @Override - public Response> zrevrankWithScore(String key, String member) { - return appendCommand(commandObjects.zrevrankWithScore(key, member)); - } - - @Override - public Response> zrange(String key, long start, long stop) { - return appendCommand(commandObjects.zrange(key, start, stop)); - } - - @Override - public Response> zrevrange(String key, long start, long stop) { - return appendCommand(commandObjects.zrevrange(key, start, stop)); - } - - @Override - public Response> zrangeWithScores(String key, long start, long stop) { - return appendCommand(commandObjects.zrangeWithScores(key, start, stop)); - } - - @Override - public Response> zrevrangeWithScores(String key, long start, long stop) { - return appendCommand(commandObjects.zrevrangeWithScores(key, start, stop)); - } - - @Override - public Response> zrange(String key, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrange(key, zRangeParams)); - } - - @Override - public Response> zrangeWithScores(String key, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrangeWithScores(key, zRangeParams)); - } - - @Override - public Response zrangestore(String dest, String src, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrangestore(dest, src, zRangeParams)); - } - - @Override - public Response zrandmember(String key) { - return appendCommand(commandObjects.zrandmember(key)); - } - - @Override - public Response> zrandmember(String key, long count) { - return appendCommand(commandObjects.zrandmember(key, count)); - } - - @Override - public Response> zrandmemberWithScores(String key, long count) { - return appendCommand(commandObjects.zrandmemberWithScores(key, count)); - } - - @Override - public Response zcard(String key) { - return appendCommand(commandObjects.zcard(key)); - } - - @Override - public Response zscore(String key, String member) { - return appendCommand(commandObjects.zscore(key, member)); - } - - @Override - public Response> zmscore(String key, String... members) { - return appendCommand(commandObjects.zmscore(key, members)); - } - - @Override - public Response zpopmax(String key) { - return appendCommand(commandObjects.zpopmax(key)); - } - - @Override - public Response> zpopmax(String key, int count) { - return appendCommand(commandObjects.zpopmax(key, count)); - } - - @Override - public Response zpopmin(String key) { - return appendCommand(commandObjects.zpopmin(key)); - } - - @Override - public Response> zpopmin(String key, int count) { - return appendCommand(commandObjects.zpopmin(key, count)); - } - - @Override - public Response zcount(String key, double min, double max) { - return appendCommand(commandObjects.zcount(key, min, max)); - } - - @Override - public Response zcount(String key, String min, String max) { - return appendCommand(commandObjects.zcount(key, min, max)); - } - - @Override - public Response> zrangeByScore(String key, double min, double max) { - return appendCommand(commandObjects.zrangeByScore(key, min, max)); - } - - @Override - public Response> zrangeByScore(String key, String min, String max) { - return appendCommand(commandObjects.zrangeByScore(key, min, max)); - } - - @Override - public Response> zrevrangeByScore(String key, double max, double min) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); - - } - - @Override - public Response> zrangeByScore(String key, double min, double max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(String key, String max, String min) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); - } - - @Override - public Response> zrangeByScore(String key, String min, String max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(String key, double max, double min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); - } - - @Override - public Response> zrangeByScoreWithScores(String key, double min, double max) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); - } - - @Override - public Response> zrevrangeByScoreWithScores(String key, double max, double min) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); - } - - @Override - public Response> zrangeByScoreWithScores(String key, double min, double max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(String key, String max, String min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); - } - - @Override - public Response> zrangeByScoreWithScores(String key, String min, String max) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); - } - - @Override - public Response> zrevrangeByScoreWithScores(String key, String max, String min) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); - } - - @Override - public Response> zrangeByScoreWithScores(String key, String min, String max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScoreWithScores(String key, double max, double min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); - } - - @Override - public Response> zrevrangeByScoreWithScores(String key, String max, String min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); - } - - @Override - public Response zremrangeByRank(String key, long start, long stop) { - return appendCommand(commandObjects.zremrangeByRank(key, start, stop)); - } - - @Override - public Response zremrangeByScore(String key, double min, double max) { - return appendCommand(commandObjects.zremrangeByScore(key, min, max)); - } - - @Override - public Response zremrangeByScore(String key, String min, String max) { - return appendCommand(commandObjects.zremrangeByScore(key, min, max)); - } - - @Override - public Response zlexcount(String key, String min, String max) { - return appendCommand(commandObjects.zlexcount(key, min, max)); - } - - @Override - public Response> zrangeByLex(String key, String min, String max) { - return appendCommand(commandObjects.zrangeByLex(key, min, max)); - } - - @Override - public Response> zrangeByLex(String key, String min, String max, int offset, int count) { - return appendCommand(commandObjects.zrangeByLex(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByLex(String key, String max, String min) { - return appendCommand(commandObjects.zrevrangeByLex(key, max, min)); - } - - @Override - public Response> zrevrangeByLex(String key, String max, String min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByLex(key, max, min, offset, count)); - } - - @Override - public Response zremrangeByLex(String key, String min, String max) { - return appendCommand(commandObjects.zremrangeByLex(key, min, max)); - } - - @Override - public Response> zscan(String key, String cursor, ScanParams params) { - return appendCommand(commandObjects.zscan(key, cursor, params)); - } - - @Override - public Response> bzpopmax(double timeout, String... keys) { - return appendCommand(commandObjects.bzpopmax(timeout, keys)); - } - - @Override - public Response> bzpopmin(double timeout, String... keys) { - return appendCommand(commandObjects.bzpopmin(timeout, keys)); - } - - @Override - public Response>> zmpop(SortedSetOption option, String... keys) { - return appendCommand(commandObjects.zmpop(option, keys)); - } - - @Override - public Response>> zmpop(SortedSetOption option, int count, String... keys) { - return appendCommand(commandObjects.zmpop(option, count, keys)); - } - - @Override - public Response>> bzmpop(double timeout, SortedSetOption option, String... keys) { - return appendCommand(commandObjects.bzmpop(timeout, option, keys)); - } - - @Override - public Response>> bzmpop(double timeout, SortedSetOption option, int count, String... keys) { - return appendCommand(commandObjects.bzmpop(timeout, option, count, keys)); - } - - @Override - public Response> zdiff(String... keys) { - return appendCommand(commandObjects.zdiff(keys)); - } - - @Override - public Response> zdiffWithScores(String... keys) { - return appendCommand(commandObjects.zdiffWithScores(keys)); - } - - @Override - @Deprecated - public Response zdiffStore(String dstKey, String... keys) { - return appendCommand(commandObjects.zdiffStore(dstKey, keys)); - } - - @Override - public Response zdiffstore(String dstKey, String... keys) { - return appendCommand(commandObjects.zdiffstore(dstKey, keys)); - } - - @Override - public Response zinterstore(String dstKey, String... sets) { - return appendCommand(commandObjects.zinterstore(dstKey, sets)); - } - - @Override - public Response zinterstore(String dstKey, ZParams params, String... sets) { - return appendCommand(commandObjects.zinterstore(dstKey, params, sets)); - } - - @Override - public Response> zinter(ZParams params, String... keys) { - return appendCommand(commandObjects.zinter(params, keys)); - } - - @Override - public Response> zinterWithScores(ZParams params, String... keys) { - return appendCommand(commandObjects.zinterWithScores(params, keys)); - } - - @Override - public Response zintercard(String... keys) { - return appendCommand(commandObjects.zintercard(keys)); - } - - @Override - public Response zintercard(long limit, String... keys) { - return appendCommand(commandObjects.zintercard(limit, keys)); - } - - @Override - public Response> zunion(ZParams params, String... keys) { - return appendCommand(commandObjects.zunion(params, keys)); - } - - @Override - public Response> zunionWithScores(ZParams params, String... keys) { - return appendCommand(commandObjects.zunionWithScores(params, keys)); - } - - @Override - public Response zunionstore(String dstKey, String... sets) { - return appendCommand(commandObjects.zunionstore(dstKey, sets)); - } - - @Override - public Response zunionstore(String dstKey, ZParams params, String... sets) { - return appendCommand(commandObjects.zunionstore(dstKey, params, sets)); - } - - @Override - public Response geoadd(String key, double longitude, double latitude, String member) { - return appendCommand(commandObjects.geoadd(key, longitude, latitude, member)); - } - - @Override - public Response geoadd(String key, Map memberCoordinateMap) { - return appendCommand(commandObjects.geoadd(key, memberCoordinateMap)); - } - - @Override - public Response geoadd(String key, GeoAddParams params, Map memberCoordinateMap) { - return appendCommand(commandObjects.geoadd(key, params, memberCoordinateMap)); - } - - @Override - public Response geodist(String key, String member1, String member2) { - return appendCommand(commandObjects.geodist(key, member1, member2)); - } - - @Override - public Response geodist(String key, String member1, String member2, GeoUnit unit) { - return appendCommand(commandObjects.geodist(key, member1, member2, unit)); - } - - @Override - public Response> geohash(String key, String... members) { - return appendCommand(commandObjects.geohash(key, members)); - } - - @Override - public Response> geopos(String key, String... members) { - return appendCommand(commandObjects.geopos(key, members)); - } - - @Override - public Response> georadius(String key, double longitude, double latitude, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit)); - } - - @Override - public Response> georadiusReadonly(String key, double longitude, double latitude, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit)); - } - - @Override - public Response> georadius(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit, param)); - } - - @Override - public Response> georadiusReadonly(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit, param)); - } - - @Override - public Response> georadiusByMember(String key, String member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit)); - } - - @Override - public Response> georadiusByMemberReadonly(String key, String member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit)); - } - - @Override - public Response> georadiusByMember(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit, param)); - } - - @Override - public Response> georadiusByMemberReadonly(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit, param)); - } - - @Override - public Response georadiusStore(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { - return appendCommand(commandObjects.georadiusStore(key, longitude, latitude, radius, unit, param, storeParam)); - } - - @Override - public Response georadiusByMemberStore(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { - return appendCommand(commandObjects.georadiusByMemberStore(key, member, radius, unit, param, storeParam)); - } - - @Override - public Response> geosearch(String key, String member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, member, radius, unit)); - } - - @Override - public Response> geosearch(String key, GeoCoordinate coord, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, coord, radius, unit)); - } - - @Override - public Response> geosearch(String key, String member, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, member, width, height, unit)); - } - - @Override - public Response> geosearch(String key, GeoCoordinate coord, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, coord, width, height, unit)); - } - - @Override - public Response> geosearch(String key, GeoSearchParam params) { - return appendCommand(commandObjects.geosearch(key, params)); - } - - @Override - public Response geosearchStore(String dest, String src, String member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, member, radius, unit)); - } - - @Override - public Response geosearchStore(String dest, String src, GeoCoordinate coord, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, coord, radius, unit)); - } - - @Override - public Response geosearchStore(String dest, String src, String member, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, member, width, height, unit)); - } - - @Override - public Response geosearchStore(String dest, String src, GeoCoordinate coord, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, coord, width, height, unit)); - } - - @Override - public Response geosearchStore(String dest, String src, GeoSearchParam params) { - return appendCommand(commandObjects.geosearchStore(dest, src, params)); - } - - @Override - public Response geosearchStoreStoreDist(String dest, String src, GeoSearchParam params) { - return appendCommand(commandObjects.geosearchStoreStoreDist(dest, src, params)); - } - - @Override - public Response pfadd(String key, String... elements) { - return appendCommand(commandObjects.pfadd(key, elements)); - } - - @Override - public Response pfmerge(String destkey, String... sourcekeys) { - return appendCommand(commandObjects.pfmerge(destkey, sourcekeys)); - } - - @Override - public Response pfcount(String key) { - return appendCommand(commandObjects.pfcount(key)); - } - - @Override - public Response pfcount(String... keys) { - return appendCommand(commandObjects.pfcount(keys)); - } - - @Override - public Response xadd(String key, StreamEntryID id, Map hash) { - return appendCommand(commandObjects.xadd(key, id, hash)); - } - - @Override - public Response xadd(String key, XAddParams params, Map hash) { - return appendCommand(commandObjects.xadd(key, params, hash)); - } - - @Override - public Response xlen(String key) { - return appendCommand(commandObjects.xlen(key)); - } - - @Override - public Response> xrange(String key, StreamEntryID start, StreamEntryID end) { - return appendCommand(commandObjects.xrange(key, start, end)); - } - - @Override - public Response> xrange(String key, StreamEntryID start, StreamEntryID end, int count) { - return appendCommand(commandObjects.xrange(key, start, end, count)); - } - - @Override - public Response> xrevrange(String key, StreamEntryID end, StreamEntryID start) { - return appendCommand(commandObjects.xrevrange(key, start, end)); - } - - @Override - public Response> xrevrange(String key, StreamEntryID end, StreamEntryID start, int count) { - return appendCommand(commandObjects.xrevrange(key, start, end, count)); - } - - @Override - public Response> xrange(String key, String start, String end) { - return appendCommand(commandObjects.xrange(key, start, end)); - } - - @Override - public Response> xrange(String key, String start, String end, int count) { - return appendCommand(commandObjects.xrange(key, start, end, count)); - } - - @Override - public Response> xrevrange(String key, String end, String start) { - return appendCommand(commandObjects.xrevrange(key, start, end)); - } - - @Override - public Response> xrevrange(String key, String end, String start, int count) { - return appendCommand(commandObjects.xrevrange(key, start, end, count)); - } - - @Override - public Response xack(String key, String group, StreamEntryID... ids) { - return appendCommand(commandObjects.xack(key, group, ids)); - } - - @Override - public Response xgroupCreate(String key, String groupName, StreamEntryID id, boolean makeStream) { - return appendCommand(commandObjects.xgroupCreate(key, groupName, id, makeStream)); - } - - @Override - public Response xgroupSetID(String key, String groupName, StreamEntryID id) { - return appendCommand(commandObjects.xgroupSetID(key, groupName, id)); - } - - @Override - public Response xgroupDestroy(String key, String groupName) { - return appendCommand(commandObjects.xgroupDestroy(key, groupName)); - } - - @Override - public Response xgroupCreateConsumer(String key, String groupName, String consumerName) { - return appendCommand(commandObjects.xgroupCreateConsumer(key, groupName, consumerName)); - } - - @Override - public Response xgroupDelConsumer(String key, String groupName, String consumerName) { - return appendCommand(commandObjects.xgroupDelConsumer(key, groupName, consumerName)); - } - - @Override - public Response xpending(String key, String groupName) { - return appendCommand(commandObjects.xpending(key, groupName)); - } - - @Override - public Response> xpending(String key, String groupName, XPendingParams params) { - return appendCommand(commandObjects.xpending(key, groupName, params)); - } - - @Override - public Response xdel(String key, StreamEntryID... ids) { - return appendCommand(commandObjects.xdel(key, ids)); - } - - @Override - public Response xtrim(String key, long maxLen, boolean approximate) { - return appendCommand(commandObjects.xtrim(key, maxLen, approximate)); - } - - @Override - public Response xtrim(String key, XTrimParams params) { - return appendCommand(commandObjects.xtrim(key, params)); - } - - @Override - public Response> xclaim(String key, String group, String consumerName, long minIdleTime, XClaimParams params, StreamEntryID... ids) { - return appendCommand(commandObjects.xclaim(key, group, consumerName, minIdleTime, params, ids)); - } - - @Override - public Response> xclaimJustId(String key, String group, String consumerName, long minIdleTime, XClaimParams params, StreamEntryID... ids) { - return appendCommand(commandObjects.xclaimJustId(key, group, consumerName, minIdleTime, params, ids)); - } - - @Override - public Response>> xautoclaim(String key, String group, String consumerName, long minIdleTime, StreamEntryID start, XAutoClaimParams params) { - return appendCommand(commandObjects.xautoclaim(key, group, consumerName, minIdleTime, start, params)); - } - - @Override - public Response>> xautoclaimJustId(String key, String group, String consumerName, long minIdleTime, StreamEntryID start, XAutoClaimParams params) { - return appendCommand(commandObjects.xautoclaimJustId(key, group, consumerName, minIdleTime, start, params)); - } - - @Override - public Response xinfoStream(String key) { - return appendCommand(commandObjects.xinfoStream(key)); - } - - @Override - public Response xinfoStreamFull(String key) { - return appendCommand(commandObjects.xinfoStreamFull(key)); - } - - @Override - public Response xinfoStreamFull(String key, int count) { - return appendCommand(commandObjects.xinfoStreamFull(key, count)); - } - - @Override - public Response> xinfoGroups(String key) { - return appendCommand(commandObjects.xinfoGroups(key)); - } - - @Override - public Response> xinfoConsumers(String key, String group) { - return appendCommand(commandObjects.xinfoConsumers(key, group)); - } - - @Override - public Response> xinfoConsumers2(String key, String group) { - return appendCommand(commandObjects.xinfoConsumers2(key, group)); - } - - @Override - public Response>>> xread(XReadParams xReadParams, Map streams) { - return appendCommand(commandObjects.xread(xReadParams, streams)); - } - - @Override - public Response>>> xreadGroup(String groupName, String consumer, XReadGroupParams xReadGroupParams, Map streams) { - return appendCommand(commandObjects.xreadGroup(groupName, consumer, xReadGroupParams, streams)); - } - - @Override - public Response eval(String script) { - return appendCommand(commandObjects.eval(script)); - } - - @Override - public Response eval(String script, int keyCount, String... params) { - return appendCommand(commandObjects.eval(script, keyCount, params)); - } - - @Override - public Response eval(String script, List keys, List args) { - return appendCommand(commandObjects.eval(script, keys, args)); - } - - @Override - public Response evalReadonly(String script, List keys, List args) { - return appendCommand(commandObjects.evalReadonly(script, keys, args)); - } - - @Override - public Response evalsha(String sha1) { - return appendCommand(commandObjects.evalsha(sha1)); - } - - @Override - public Response evalsha(String sha1, int keyCount, String... params) { - return appendCommand(commandObjects.evalsha(sha1, keyCount, params)); - } - - @Override - public Response evalsha(String sha1, List keys, List args) { - return appendCommand(commandObjects.evalsha(sha1, keys, args)); - } - - @Override - public Response evalshaReadonly(String sha1, List keys, List args) { - return appendCommand(commandObjects.evalshaReadonly(sha1, keys, args)); - } - - - @Override - public Response waitReplicas(String sampleKey, int replicas, long timeout) { - return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout)); - } - - @Override - public Response> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout) { - return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout)); - } - - @Override - public Response eval(String script, String sampleKey) { - return appendCommand(commandObjects.eval(script, sampleKey)); - } - - @Override - public Response evalsha(String sha1, String sampleKey) { - return appendCommand(commandObjects.evalsha(sha1, sampleKey)); - } - - @Override - public Response> scriptExists(String sampleKey, String... sha1) { - return appendCommand(commandObjects.scriptExists(sampleKey, sha1)); - } - - @Override - public Response scriptLoad(String script, String sampleKey) { - return appendCommand(commandObjects.scriptLoad(script, sampleKey)); - } - - @Override - public Response scriptFlush(String sampleKey) { - return appendCommand(commandObjects.scriptFlush(sampleKey)); - } - - @Override - public Response scriptFlush(String sampleKey, FlushMode flushMode) { - return appendCommand(commandObjects.scriptFlush(sampleKey, flushMode)); - } - - @Override - public Response scriptKill(String sampleKey) { - return appendCommand(commandObjects.scriptKill(sampleKey)); - } - - @Override - public Response fcall(byte[] name, List keys, List args) { - return appendCommand(commandObjects.fcall(name, keys, args)); - } - - @Override - public Response fcall(String name, List keys, List args) { - return appendCommand(commandObjects.fcall(name, keys, args)); - } - - @Override - public Response fcallReadonly(byte[] name, List keys, List args) { - return appendCommand(commandObjects.fcallReadonly(name, keys, args)); - } - - @Override - public Response fcallReadonly(String name, List keys, List args) { - return appendCommand(commandObjects.fcallReadonly(name, keys, args)); - } - - @Override - public Response functionDelete(byte[] libraryName) { - return appendCommand(commandObjects.functionDelete(libraryName)); - } - - @Override - public Response functionDelete(String libraryName) { - return appendCommand(commandObjects.functionDelete(libraryName)); - } - - @Override - public Response functionDump() { - return appendCommand(commandObjects.functionDump()); - } - - @Override - public Response> functionList(String libraryNamePattern) { - return appendCommand(commandObjects.functionList(libraryNamePattern)); - } - - @Override - public Response> functionList() { - return appendCommand(commandObjects.functionList()); - } - - @Override - public Response> functionListWithCode(String libraryNamePattern) { - return appendCommand(commandObjects.functionListWithCode(libraryNamePattern)); - } - - @Override - public Response> functionListWithCode() { - return appendCommand(commandObjects.functionListWithCode()); - } - - @Override - public Response> functionListBinary() { - return appendCommand(commandObjects.functionListBinary()); - } - - @Override - public Response> functionList(final byte[] libraryNamePattern) { - return appendCommand(commandObjects.functionList(libraryNamePattern)); - } - - @Override - public Response> functionListWithCodeBinary() { - return appendCommand(commandObjects.functionListWithCodeBinary()); - } - - @Override - public Response> functionListWithCode(final byte[] libraryNamePattern) { - return appendCommand(commandObjects.functionListWithCode(libraryNamePattern)); - } - - @Override - public Response functionLoad(byte[] functionCode) { - return appendCommand(commandObjects.functionLoad(functionCode)); - } - - @Override - public Response functionLoad(String functionCode) { - return appendCommand(commandObjects.functionLoad(functionCode)); - } - - @Override - public Response functionLoadReplace(byte[] functionCode) { - return appendCommand(commandObjects.functionLoadReplace(functionCode)); - } - - @Override - public Response functionLoadReplace(String functionCode) { - return appendCommand(commandObjects.functionLoadReplace(functionCode)); - } - - @Override - public Response functionRestore(byte[] serializedValue) { - return appendCommand(commandObjects.functionRestore(serializedValue)); - } - - @Override - public Response functionRestore(byte[] serializedValue, FunctionRestorePolicy policy) { - return appendCommand(commandObjects.functionRestore(serializedValue, policy)); - } - - @Override - public Response functionFlush() { - return appendCommand(commandObjects.functionFlush()); - } - - @Override - public Response functionFlush(FlushMode mode) { - return appendCommand(commandObjects.functionFlush(mode)); - } - - @Override - public Response functionKill() { - return appendCommand(commandObjects.functionKill()); - } - - @Override - public Response functionStats() { - return appendCommand(commandObjects.functionStats()); - } - - @Override - public Response functionStatsBinary() { - return appendCommand(commandObjects.functionStatsBinary()); - } - - public Response publish(String channel, String message) { - return appendCommand(commandObjects.publish(channel, message)); - } - - @Override - public Response geoadd(byte[] key, double longitude, double latitude, byte[] member) { - return appendCommand(commandObjects.geoadd(key, longitude, latitude, member)); - } - - @Override - public Response geoadd(byte[] key, Map memberCoordinateMap) { - return appendCommand(commandObjects.geoadd(key, memberCoordinateMap)); - } - - @Override - public Response geoadd(byte[] key, GeoAddParams params, Map memberCoordinateMap) { - return appendCommand(commandObjects.geoadd(key, params, memberCoordinateMap)); - } - - @Override - public Response geodist(byte[] key, byte[] member1, byte[] member2) { - return appendCommand(commandObjects.geodist(key, member1, member2)); - } - - @Override - public Response geodist(byte[] key, byte[] member1, byte[] member2, GeoUnit unit) { - return appendCommand(commandObjects.geodist(key, member1, member2, unit)); - } - - @Override - public Response> geohash(byte[] key, byte[]... members) { - return appendCommand(commandObjects.geohash(key, members)); - } - - @Override - public Response> geopos(byte[] key, byte[]... members) { - return appendCommand(commandObjects.geopos(key, members)); - } - - @Override - public Response> georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit)); - } - - @Override - public Response> georadiusReadonly(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit)); - } - - @Override - public Response> georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadius(key, longitude, latitude, radius, unit, param)); - } - - @Override - public Response> georadiusReadonly(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusReadonly(key, longitude, latitude, radius, unit, param)); - } - - @Override - public Response> georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit)); - } - - @Override - public Response> georadiusByMemberReadonly(byte[] key, byte[] member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit)); - } - - @Override - public Response> georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusByMember(key, member, radius, unit, param)); - } - - @Override - public Response> georadiusByMemberReadonly(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { - return appendCommand(commandObjects.georadiusByMemberReadonly(key, member, radius, unit, param)); - } - - @Override - public Response georadiusStore(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { - return appendCommand(commandObjects.georadiusStore(key, longitude, latitude, radius, unit, param, storeParam)); - } - - @Override - public Response georadiusByMemberStore(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param, GeoRadiusStoreParam storeParam) { - return appendCommand(commandObjects.georadiusByMemberStore(key, member, radius, unit, param, storeParam)); - } - - @Override - public Response> geosearch(byte[] key, byte[] member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, member, radius, unit)); - } - - @Override - public Response> geosearch(byte[] key, GeoCoordinate coord, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, coord, radius, unit)); - } - - @Override - public Response> geosearch(byte[] key, byte[] member, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, member, width, height, unit)); - } - - @Override - public Response> geosearch(byte[] key, GeoCoordinate coord, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearch(key, coord, width, height, unit)); - } - - @Override - public Response> geosearch(byte[] key, GeoSearchParam params) { - return appendCommand(commandObjects.geosearch(key, params)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, byte[] member, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, member, radius, unit)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, GeoCoordinate coord, double radius, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, coord, radius, unit)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, byte[] member, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, member, width, height, unit)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, GeoCoordinate coord, double width, double height, GeoUnit unit) { - return appendCommand(commandObjects.geosearchStore(dest, src, coord, width, height, unit)); - } - - @Override - public Response geosearchStore(byte[] dest, byte[] src, GeoSearchParam params) { - return appendCommand(commandObjects.geosearchStore(dest, src, params)); - } - - @Override - public Response geosearchStoreStoreDist(byte[] dest, byte[] src, GeoSearchParam params) { - return appendCommand(commandObjects.geosearchStoreStoreDist(dest, src, params)); - } - - @Override - public Response hset(byte[] key, byte[] field, byte[] value) { - return appendCommand(commandObjects.hset(key, field, value)); - } - - @Override - public Response hset(byte[] key, Map hash) { - return appendCommand(commandObjects.hset(key, hash)); - } - - @Override - public Response hget(byte[] key, byte[] field) { - return appendCommand(commandObjects.hget(key, field)); - } - - @Override - public Response hsetnx(byte[] key, byte[] field, byte[] value) { - return appendCommand(commandObjects.hsetnx(key, field, value)); - } - - @Override - public Response hmset(byte[] key, Map hash) { - return appendCommand(commandObjects.hmset(key, hash)); - } - - @Override - public Response> hmget(byte[] key, byte[]... fields) { - return appendCommand(commandObjects.hmget(key, fields)); - } - - @Override - public Response hincrBy(byte[] key, byte[] field, long value) { - return appendCommand(commandObjects.hincrBy(key, field, value)); - } - - @Override - public Response hincrByFloat(byte[] key, byte[] field, double value) { - return appendCommand(commandObjects.hincrByFloat(key, field, value)); - } - - @Override - public Response hexists(byte[] key, byte[] field) { - return appendCommand(commandObjects.hexists(key, field)); - } - - @Override - public Response hdel(byte[] key, byte[]... field) { - return appendCommand(commandObjects.hdel(key, field)); - } - - @Override - public Response hlen(byte[] key) { - return appendCommand(commandObjects.hlen(key)); - } - - @Override - public Response> hkeys(byte[] key) { - return appendCommand(commandObjects.hkeys(key)); - } - - @Override - public Response> hvals(byte[] key) { - return appendCommand(commandObjects.hvals(key)); - } - - @Override - public Response> hgetAll(byte[] key) { - return appendCommand(commandObjects.hgetAll(key)); - } - - @Override - public Response hrandfield(byte[] key) { - return appendCommand(commandObjects.hrandfield(key)); - } - - @Override - public Response> hrandfield(byte[] key, long count) { - return appendCommand(commandObjects.hrandfield(key, count)); - } - - @Override - public Response>> hrandfieldWithValues(byte[] key, long count) { - return appendCommand(commandObjects.hrandfieldWithValues(key, count)); - } - - @Override - public Response>> hscan(byte[] key, byte[] cursor, ScanParams params) { - return appendCommand(commandObjects.hscan(key, cursor, params)); - } - - @Override - public Response hstrlen(byte[] key, byte[] field) { - return appendCommand(commandObjects.hstrlen(key, field)); - } - - @Override - public Response pfadd(byte[] key, byte[]... elements) { - return appendCommand(commandObjects.pfadd(key, elements)); - } - - @Override - public Response pfmerge(byte[] destkey, byte[]... sourcekeys) { - return appendCommand(commandObjects.pfmerge(destkey, sourcekeys)); - } - - @Override - public Response pfcount(byte[] key) { - return appendCommand(commandObjects.pfcount(key)); - } - - @Override - public Response pfcount(byte[]... keys) { - return appendCommand(commandObjects.pfcount(keys)); - } - - @Override - public Response exists(byte[] key) { - return appendCommand(commandObjects.exists(key)); - } - - @Override - public Response exists(byte[]... keys) { - return appendCommand(commandObjects.exists(keys)); - } - - @Override - public Response persist(byte[] key) { - return appendCommand(commandObjects.persist(key)); - } - - @Override - public Response type(byte[] key) { - return appendCommand(commandObjects.type(key)); - } - - @Override - public Response dump(byte[] key) { - return appendCommand(commandObjects.dump(key)); - } - - @Override - public Response restore(byte[] key, long ttl, byte[] serializedValue) { - return appendCommand(commandObjects.restore(key, ttl, serializedValue)); - } - - @Override - public Response restore(byte[] key, long ttl, byte[] serializedValue, RestoreParams params) { - return appendCommand(commandObjects.restore(key, ttl, serializedValue, params)); - } - - @Override - public Response expire(byte[] key, long seconds) { - return appendCommand(commandObjects.expire(key, seconds)); - } - - @Override - public Response expire(byte[] key, long seconds, ExpiryOption expiryOption) { - return appendCommand(commandObjects.expire(key, seconds, expiryOption)); - } - - @Override - public Response pexpire(byte[] key, long milliseconds) { - return appendCommand(commandObjects.pexpire(key, milliseconds)); - } - - @Override - public Response pexpire(byte[] key, long milliseconds, ExpiryOption expiryOption) { - return appendCommand(commandObjects.pexpire(key, milliseconds, expiryOption)); - } - - @Override - public Response expireTime(byte[] key) { - return appendCommand(commandObjects.expireTime(key)); - } - - @Override - public Response pexpireTime(byte[] key) { - return appendCommand(commandObjects.pexpireTime(key)); - } - - @Override - public Response expireAt(byte[] key, long unixTime) { - return appendCommand(commandObjects.expireAt(key, unixTime)); - } - - @Override - public Response expireAt(byte[] key, long unixTime, ExpiryOption expiryOption) { - return appendCommand(commandObjects.expireAt(key, unixTime, expiryOption)); - } - - @Override - public Response pexpireAt(byte[] key, long millisecondsTimestamp) { - return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp)); - } - - @Override - public Response pexpireAt(byte[] key, long millisecondsTimestamp, ExpiryOption expiryOption) { - return appendCommand(commandObjects.pexpireAt(key, millisecondsTimestamp, expiryOption)); - } - - @Override - public Response ttl(byte[] key) { - return appendCommand(commandObjects.ttl(key)); - } - - @Override - public Response pttl(byte[] key) { - return appendCommand(commandObjects.pttl(key)); - } - - @Override - public Response touch(byte[] key) { - return appendCommand(commandObjects.touch(key)); - } - - @Override - public Response touch(byte[]... keys) { - return appendCommand(commandObjects.touch(keys)); - } - - @Override - public Response> sort(byte[] key) { - return appendCommand(commandObjects.sort(key)); - } - - @Override - public Response> sort(byte[] key, SortingParams sortingParams) { - return appendCommand(commandObjects.sort(key, sortingParams)); - } - - @Override - public Response> sortReadonly(byte[] key, SortingParams sortingParams) { - return appendCommand(commandObjects.sortReadonly(key, sortingParams)); - } - - @Override - public Response del(byte[] key) { - return appendCommand(commandObjects.del(key)); - } - - @Override - public Response del(byte[]... keys) { - return appendCommand(commandObjects.del(keys)); - } - - @Override - public Response unlink(byte[] key) { - return appendCommand(commandObjects.unlink(key)); - } - - @Override - public Response unlink(byte[]... keys) { - return appendCommand(commandObjects.unlink(keys)); - } - - @Override - public Response copy(byte[] srcKey, byte[] dstKey, boolean replace) { - return appendCommand(commandObjects.copy(srcKey, dstKey, replace)); - } - - @Override - public Response rename(byte[] oldkey, byte[] newkey) { - return appendCommand(commandObjects.rename(oldkey, newkey)); - } - - @Override - public Response renamenx(byte[] oldkey, byte[] newkey) { - return appendCommand(commandObjects.renamenx(oldkey, newkey)); - } - - @Override - public Response sort(byte[] key, SortingParams sortingParams, byte[] dstkey) { - return appendCommand(commandObjects.sort(key, sortingParams, dstkey)); - } - - @Override - public Response sort(byte[] key, byte[] dstkey) { - return appendCommand(commandObjects.sort(key, dstkey)); - } - - @Override - public Response memoryUsage(byte[] key) { - return appendCommand(commandObjects.memoryUsage(key)); - } - - @Override - public Response memoryUsage(byte[] key, int samples) { - return appendCommand(commandObjects.memoryUsage(key, samples)); - } - - @Override - public Response objectRefcount(byte[] key) { - return appendCommand(commandObjects.objectRefcount(key)); - } - - @Override - public Response objectEncoding(byte[] key) { - return appendCommand(commandObjects.objectEncoding(key)); - } - - @Override - public Response objectIdletime(byte[] key) { - return appendCommand(commandObjects.objectIdletime(key)); - } - - @Override - public Response objectFreq(byte[] key) { - return appendCommand(commandObjects.objectFreq(key)); - } - - @Override - public Response migrate(String host, int port, byte[] key, int timeout) { - return appendCommand(commandObjects.migrate(host, port, key, timeout)); - } - - @Override - public Response migrate(String host, int port, int timeout, MigrateParams params, byte[]... keys) { - return appendCommand(commandObjects.migrate(host, port, timeout, params, keys)); - } - - @Override - public Response> keys(byte[] pattern) { - return appendCommand(commandObjects.keys(pattern)); - } - - @Override - public Response> scan(byte[] cursor) { - return appendCommand(commandObjects.scan(cursor)); - } - - @Override - public Response> scan(byte[] cursor, ScanParams params) { - return appendCommand(commandObjects.scan(cursor, params)); - } - - @Override - public Response> scan(byte[] cursor, ScanParams params, byte[] type) { - return appendCommand(commandObjects.scan(cursor, params, type)); - } - - @Override - public Response randomBinaryKey() { - return appendCommand(commandObjects.randomBinaryKey()); - } - - @Override - public Response rpush(byte[] key, byte[]... args) { - return appendCommand(commandObjects.rpush(key, args)); - } - - @Override - public Response lpush(byte[] key, byte[]... args) { - return appendCommand(commandObjects.lpush(key, args)); - } - - @Override - public Response llen(byte[] key) { - return appendCommand(commandObjects.llen(key)); - } - - @Override - public Response> lrange(byte[] key, long start, long stop) { - return appendCommand(commandObjects.lrange(key, start, stop)); - } - - @Override - public Response ltrim(byte[] key, long start, long stop) { - return appendCommand(commandObjects.ltrim(key, start, stop)); - } - - @Override - public Response lindex(byte[] key, long index) { - return appendCommand(commandObjects.lindex(key, index)); - } - - @Override - public Response lset(byte[] key, long index, byte[] value) { - return appendCommand(commandObjects.lset(key, index, value)); - } - - @Override - public Response lrem(byte[] key, long count, byte[] value) { - return appendCommand(commandObjects.lrem(key, count, value)); - } - - @Override - public Response lpop(byte[] key) { - return appendCommand(commandObjects.lpop(key)); - } - - @Override - public Response> lpop(byte[] key, int count) { - return appendCommand(commandObjects.lpop(key, count)); - } - - @Override - public Response lpos(byte[] key, byte[] element) { - return appendCommand(commandObjects.lpos(key, element)); - } - - @Override - public Response lpos(byte[] key, byte[] element, LPosParams params) { - return appendCommand(commandObjects.lpos(key, element, params)); - } - - @Override - public Response> lpos(byte[] key, byte[] element, LPosParams params, long count) { - return appendCommand(commandObjects.lpos(key, element, params, count)); - } - - @Override - public Response rpop(byte[] key) { - return appendCommand(commandObjects.rpop(key)); - } - - @Override - public Response> rpop(byte[] key, int count) { - return appendCommand(commandObjects.rpop(key, count)); - } - - @Override - public Response linsert(byte[] key, ListPosition where, byte[] pivot, byte[] value) { - return appendCommand(commandObjects.linsert(key, where, pivot, value)); - } - - @Override - public Response lpushx(byte[] key, byte[]... args) { - return appendCommand(commandObjects.lpushx(key, args)); - } - - @Override - public Response rpushx(byte[] key, byte[]... args) { - return appendCommand(commandObjects.rpushx(key, args)); - } - - @Override - public Response> blpop(int timeout, byte[]... keys) { - return appendCommand(commandObjects.blpop(timeout, keys)); - } - - @Override - public Response> blpop(double timeout, byte[]... keys) { - return appendCommand(commandObjects.blpop(timeout, keys)); - } - - @Override - public Response> brpop(int timeout, byte[]... keys) { - return appendCommand(commandObjects.brpop(timeout, keys)); - } - - @Override - public Response> brpop(double timeout, byte[]... keys) { - return appendCommand(commandObjects.brpop(timeout, keys)); - } - - @Override - public Response rpoplpush(byte[] srckey, byte[] dstkey) { - return appendCommand(commandObjects.rpoplpush(srckey, dstkey)); - } - - @Override - public Response brpoplpush(byte[] source, byte[] destination, int timeout) { - return appendCommand(commandObjects.brpoplpush(source, destination, timeout)); - } - - @Override - public Response lmove(byte[] srcKey, byte[] dstKey, ListDirection from, ListDirection to) { - return appendCommand(commandObjects.lmove(srcKey, dstKey, from, to)); - } - - @Override - public Response blmove(byte[] srcKey, byte[] dstKey, ListDirection from, ListDirection to, double timeout) { - return appendCommand(commandObjects.blmove(srcKey, dstKey, from, to, timeout)); - } - - @Override - public Response>> lmpop(ListDirection direction, byte[]... keys) { - return appendCommand(commandObjects.lmpop(direction, keys)); - } - - @Override - public Response>> lmpop(ListDirection direction, int count, byte[]... keys) { - return appendCommand(commandObjects.lmpop(direction, count, keys)); - } - - @Override - public Response>> blmpop(double timeout, ListDirection direction, byte[]... keys) { - return appendCommand(commandObjects.blmpop(timeout, direction, keys)); - } - - @Override - public Response>> blmpop(double timeout, ListDirection direction, int count, byte[]... keys) { - return appendCommand(commandObjects.blmpop(timeout, direction, count, keys)); - } - - public Response publish(byte[] channel, byte[] message) { - return appendCommand(commandObjects.publish(channel, message)); - } - - @Override - public Response waitReplicas(byte[] sampleKey, int replicas, long timeout) { - return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout)); - } - - @Override - public Response> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout) { - return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout)); - } - - @Override - public Response eval(byte[] script, byte[] sampleKey) { - return appendCommand(commandObjects.eval(script, sampleKey)); - } - - @Override - public Response evalsha(byte[] sha1, byte[] sampleKey) { - return appendCommand(commandObjects.evalsha(sha1, sampleKey)); - } - - @Override - public Response> scriptExists(byte[] sampleKey, byte[]... sha1s) { - return appendCommand(commandObjects.scriptExists(sampleKey, sha1s)); - } - - @Override - public Response scriptLoad(byte[] script, byte[] sampleKey) { - return appendCommand(commandObjects.scriptLoad(script, sampleKey)); - } - - @Override - public Response scriptFlush(byte[] sampleKey) { - return appendCommand(commandObjects.scriptFlush(sampleKey)); - } - - @Override - public Response scriptFlush(byte[] sampleKey, FlushMode flushMode) { - return appendCommand(commandObjects.scriptFlush(sampleKey, flushMode)); - } - - @Override - public Response scriptKill(byte[] sampleKey) { - return appendCommand(commandObjects.scriptKill(sampleKey)); - } - - @Override - public Response eval(byte[] script) { - return appendCommand(commandObjects.eval(script)); - } - - @Override - public Response eval(byte[] script, int keyCount, byte[]... params) { - return appendCommand(commandObjects.eval(script, keyCount, params)); - } - - @Override - public Response eval(byte[] script, List keys, List args) { - return appendCommand(commandObjects.eval(script, keys, args)); - } - - @Override - public Response evalReadonly(byte[] script, List keys, List args) { - return appendCommand(commandObjects.evalReadonly(script, keys, args)); - } - - @Override - public Response evalsha(byte[] sha1) { - return appendCommand(commandObjects.evalsha(sha1)); - } - - @Override - public Response evalsha(byte[] sha1, int keyCount, byte[]... params) { - return appendCommand(commandObjects.evalsha(sha1, keyCount, params)); - } - - @Override - public Response evalsha(byte[] sha1, List keys, List args) { - return appendCommand(commandObjects.evalsha(sha1, keys, args)); - } - - @Override - public Response evalshaReadonly(byte[] sha1, List keys, List args) { - return appendCommand(commandObjects.evalshaReadonly(sha1, keys, args)); - } - - @Override - public Response sadd(byte[] key, byte[]... members) { - return appendCommand(commandObjects.sadd(key, members)); - } - - @Override - public Response> smembers(byte[] key) { - return appendCommand(commandObjects.smembers(key)); - } - - @Override - public Response srem(byte[] key, byte[]... members) { - return appendCommand(commandObjects.srem(key, members)); - } - - @Override - public Response spop(byte[] key) { - return appendCommand(commandObjects.spop(key)); - } - - @Override - public Response> spop(byte[] key, long count) { - return appendCommand(commandObjects.spop(key, count)); - } - - @Override - public Response scard(byte[] key) { - return appendCommand(commandObjects.scard(key)); - } - - @Override - public Response sismember(byte[] key, byte[] member) { - return appendCommand(commandObjects.sismember(key, member)); - } - - @Override - public Response> smismember(byte[] key, byte[]... members) { - return appendCommand(commandObjects.smismember(key, members)); - } - - @Override - public Response srandmember(byte[] key) { - return appendCommand(commandObjects.srandmember(key)); - } - - @Override - public Response> srandmember(byte[] key, int count) { - return appendCommand(commandObjects.srandmember(key, count)); - } - - @Override - public Response> sscan(byte[] key, byte[] cursor, ScanParams params) { - return appendCommand(commandObjects.sscan(key, cursor, params)); - } - - @Override - public Response> sdiff(byte[]... keys) { - return appendCommand(commandObjects.sdiff(keys)); - } - - @Override - public Response sdiffstore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.sdiffstore(dstkey, keys)); - } - - @Override - public Response> sinter(byte[]... keys) { - return appendCommand(commandObjects.sinter(keys)); - } - - @Override - public Response sinterstore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.sinterstore(dstkey, keys)); - } - - @Override - public Response sintercard(byte[]... keys) { - return appendCommand(commandObjects.sintercard(keys)); - } - - @Override - public Response sintercard(int limit, byte[]... keys) { - return appendCommand(commandObjects.sintercard(limit, keys)); - } - - @Override - public Response> sunion(byte[]... keys) { - return appendCommand(commandObjects.sunion(keys)); - } - - @Override - public Response sunionstore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.sunionstore(dstkey, keys)); - } - - @Override - public Response smove(byte[] srckey, byte[] dstkey, byte[] member) { - return appendCommand(commandObjects.smove(srckey, dstkey, member)); - } - - @Override - public Response zadd(byte[] key, double score, byte[] member) { - return appendCommand(commandObjects.zadd(key, score, member)); - } - - @Override - public Response zadd(byte[] key, double score, byte[] member, ZAddParams params) { - return appendCommand(commandObjects.zadd(key, score, member, params)); - } - - @Override - public Response zadd(byte[] key, Map scoreMembers) { - return appendCommand(commandObjects.zadd(key, scoreMembers)); - } - - @Override - public Response zadd(byte[] key, Map scoreMembers, ZAddParams params) { - return appendCommand(commandObjects.zadd(key, scoreMembers, params)); - } - - @Override - public Response zaddIncr(byte[] key, double score, byte[] member, ZAddParams params) { - return appendCommand(commandObjects.zaddIncr(key, score, member, params)); - } - - @Override - public Response zrem(byte[] key, byte[]... members) { - return appendCommand(commandObjects.zrem(key, members)); - } - - @Override - public Response zincrby(byte[] key, double increment, byte[] member) { - return appendCommand(commandObjects.zincrby(key, increment, member)); - } - - @Override - public Response zincrby(byte[] key, double increment, byte[] member, ZIncrByParams params) { - return appendCommand(commandObjects.zincrby(key, increment, member, params)); - } - - @Override - public Response zrank(byte[] key, byte[] member) { - return appendCommand(commandObjects.zrank(key, member)); - } - - @Override - public Response zrevrank(byte[] key, byte[] member) { - return appendCommand(commandObjects.zrevrank(key, member)); - } - - @Override - public Response> zrankWithScore(byte[] key, byte[] member) { - return appendCommand(commandObjects.zrankWithScore(key, member)); - } - - @Override - public Response> zrevrankWithScore(byte[] key, byte[] member) { - return appendCommand(commandObjects.zrevrankWithScore(key, member)); - } - - @Override - public Response> zrange(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zrange(key, start, stop)); - } - - @Override - public Response> zrevrange(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zrevrange(key, start, stop)); - } - - @Override - public Response> zrangeWithScores(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zrangeWithScores(key, start, stop)); - } - - @Override - public Response> zrevrangeWithScores(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zrevrangeWithScores(key, start, stop)); - } - - @Override - public Response> zrange(byte[] key, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrange(key, zRangeParams)); - } - - @Override - public Response> zrangeWithScores(byte[] key, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrangeWithScores(key, zRangeParams)); - } - - @Override - public Response zrangestore(byte[] dest, byte[] src, ZRangeParams zRangeParams) { - return appendCommand(commandObjects.zrangestore(dest, src, zRangeParams)); - } - - @Override - public Response zrandmember(byte[] key) { - return appendCommand(commandObjects.zrandmember(key)); - } - - @Override - public Response> zrandmember(byte[] key, long count) { - return appendCommand(commandObjects.zrandmember(key, count)); - } - - @Override - public Response> zrandmemberWithScores(byte[] key, long count) { - return appendCommand(commandObjects.zrandmemberWithScores(key, count)); - } - - @Override - public Response zcard(byte[] key) { - return appendCommand(commandObjects.zcard(key)); - } - - @Override - public Response zscore(byte[] key, byte[] member) { - return appendCommand(commandObjects.zscore(key, member)); - } - - @Override - public Response> zmscore(byte[] key, byte[]... members) { - return appendCommand(commandObjects.zmscore(key, members)); - } - - @Override - public Response zpopmax(byte[] key) { - return appendCommand(commandObjects.zpopmax(key)); - } - - @Override - public Response> zpopmax(byte[] key, int count) { - return appendCommand(commandObjects.zpopmax(key, count)); - } - - @Override - public Response zpopmin(byte[] key) { - return appendCommand(commandObjects.zpopmin(key)); - } - - @Override - public Response> zpopmin(byte[] key, int count) { - return appendCommand(commandObjects.zpopmin(key, count)); - } - - @Override - public Response zcount(byte[] key, double min, double max) { - return appendCommand(commandObjects.zcount(key, min, max)); - } - - @Override - public Response zcount(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zcount(key, min, max)); - } - - @Override - public Response> zrangeByScore(byte[] key, double min, double max) { - return appendCommand(commandObjects.zrangeByScore(key, min, max)); - } - - @Override - public Response> zrangeByScore(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zrangeByScore(key, min, max)); - } - - @Override - public Response> zrevrangeByScore(byte[] key, double max, double min) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); - } - - @Override - public Response> zrangeByScore(byte[] key, double min, double max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(byte[] key, byte[] max, byte[] min) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min)); - } - - @Override - public Response> zrangeByScore(byte[] key, byte[] min, byte[] max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScore(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(byte[] key, double max, double min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); - } - - @Override - public Response> zrangeByScoreWithScores(byte[] key, double min, double max) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); - } - - @Override - public Response> zrevrangeByScoreWithScores(byte[] key, double max, double min) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); - } - - @Override - public Response> zrangeByScoreWithScores(byte[] key, double min, double max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScore(byte[] key, byte[] max, byte[] min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count)); - } - - @Override - public Response> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max)); - } - - @Override - public Response> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min)); - } - - @Override - public Response> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max, int offset, int count) { - return appendCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByScoreWithScores(byte[] key, double max, double min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); - } - - @Override - public Response> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count)); - } - - @Override - public Response zremrangeByRank(byte[] key, long start, long stop) { - return appendCommand(commandObjects.zremrangeByRank(key, start, stop)); - } - - @Override - public Response zremrangeByScore(byte[] key, double min, double max) { - return appendCommand(commandObjects.zremrangeByScore(key, min, max)); - } - - @Override - public Response zremrangeByScore(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zremrangeByScore(key, min, max)); - } - - @Override - public Response zlexcount(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zlexcount(key, min, max)); - } - - @Override - public Response> zrangeByLex(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zrangeByLex(key, min, max)); - } - - @Override - public Response> zrangeByLex(byte[] key, byte[] min, byte[] max, int offset, int count) { - return appendCommand(commandObjects.zrangeByLex(key, min, max, offset, count)); - } - - @Override - public Response> zrevrangeByLex(byte[] key, byte[] max, byte[] min) { - return appendCommand(commandObjects.zrevrangeByLex(key, min, max)); - } - - @Override - public Response> zrevrangeByLex(byte[] key, byte[] max, byte[] min, int offset, int count) { - return appendCommand(commandObjects.zrevrangeByLex(key, min, max, offset, count)); - } - - @Override - public Response zremrangeByLex(byte[] key, byte[] min, byte[] max) { - return appendCommand(commandObjects.zremrangeByLex(key, min, max)); - } - - @Override - public Response> zscan(byte[] key, byte[] cursor, ScanParams params) { - return appendCommand(commandObjects.zscan(key, cursor, params)); - } - - @Override - public Response> bzpopmax(double timeout, byte[]... keys) { - return appendCommand(commandObjects.bzpopmax(timeout, keys)); - } - - @Override - public Response> bzpopmin(double timeout, byte[]... keys) { - return appendCommand(commandObjects.bzpopmin(timeout, keys)); - } - - @Override - public Response>> zmpop(SortedSetOption option, byte[]... keys) { - return appendCommand(commandObjects.zmpop(option, keys)); - } - - @Override - public Response>> zmpop(SortedSetOption option, int count, byte[]... keys) { - return appendCommand(commandObjects.zmpop(option, count, keys)); - } - - @Override - public Response>> bzmpop(double timeout, SortedSetOption option, byte[]... keys) { - return appendCommand(commandObjects.bzmpop(timeout, option, keys)); - } - - @Override - public Response>> bzmpop(double timeout, SortedSetOption option, int count, byte[]... keys) { - return appendCommand(commandObjects.bzmpop(timeout, option, count, keys)); - } - - @Override - public Response> zdiff(byte[]... keys) { - return appendCommand(commandObjects.zdiff(keys)); - } - - @Override - public Response> zdiffWithScores(byte[]... keys) { - return appendCommand(commandObjects.zdiffWithScores(keys)); - } - - @Override - @Deprecated - public Response zdiffStore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.zdiffStore(dstkey, keys)); - } - - @Override - public Response zdiffstore(byte[] dstkey, byte[]... keys) { - return appendCommand(commandObjects.zdiffstore(dstkey, keys)); - } - - @Override - public Response> zinter(ZParams params, byte[]... keys) { - return appendCommand(commandObjects.zinter(params, keys)); - } - - @Override - public Response> zinterWithScores(ZParams params, byte[]... keys) { - return appendCommand(commandObjects.zinterWithScores(params, keys)); - } - - @Override - public Response zinterstore(byte[] dstkey, byte[]... sets) { - return appendCommand(commandObjects.zinterstore(dstkey, sets)); - } - - @Override - public Response zinterstore(byte[] dstkey, ZParams params, byte[]... sets) { - return appendCommand(commandObjects.zinterstore(dstkey, params, sets)); - } - - @Override - public Response zintercard(byte[]... keys) { - return appendCommand(commandObjects.zintercard(keys)); - } - - @Override - public Response zintercard(long limit, byte[]... keys) { - return appendCommand(commandObjects.zintercard(limit, keys)); - } - - @Override - public Response> zunion(ZParams params, byte[]... keys) { - return appendCommand(commandObjects.zunion(params, keys)); - } - - @Override - public Response> zunionWithScores(ZParams params, byte[]... keys) { - return appendCommand(commandObjects.zunionWithScores(params, keys)); - } - - @Override - public Response zunionstore(byte[] dstkey, byte[]... sets) { - return appendCommand(commandObjects.zunionstore(dstkey, sets)); - } - - @Override - public Response zunionstore(byte[] dstkey, ZParams params, byte[]... sets) { - return appendCommand(commandObjects.zunionstore(dstkey, params, sets)); - } - - @Override - public Response xadd(byte[] key, XAddParams params, Map hash) { - return appendCommand(commandObjects.xadd(key, params, hash)); - } - - @Override - public Response xlen(byte[] key) { - return appendCommand(commandObjects.xlen(key)); - } - - @Override - public Response> xrange(byte[] key, byte[] start, byte[] end) { - return appendCommand(commandObjects.xrange(key, start, end)); - } - - @Override - public Response> xrange(byte[] key, byte[] start, byte[] end, int count) { - return appendCommand(commandObjects.xrange(key, start, end, count)); - } - - @Override - public Response> xrevrange(byte[] key, byte[] end, byte[] start) { - return appendCommand(commandObjects.xrevrange(key, end, start)); - } - - @Override - public Response> xrevrange(byte[] key, byte[] end, byte[] start, int count) { - return appendCommand(commandObjects.xrevrange(key, end, start, count)); - } - - @Override - public Response xack(byte[] key, byte[] group, byte[]... ids) { - return appendCommand(commandObjects.xack(key, group, ids)); - } - - @Override - public Response xgroupCreate(byte[] key, byte[] groupName, byte[] id, boolean makeStream) { - return appendCommand(commandObjects.xgroupCreate(key, groupName, id, makeStream)); - } - - @Override - public Response xgroupSetID(byte[] key, byte[] groupName, byte[] id) { - return appendCommand(commandObjects.xgroupSetID(key, groupName, id)); - } - - @Override - public Response xgroupDestroy(byte[] key, byte[] groupName) { - return appendCommand(commandObjects.xgroupDestroy(key, groupName)); - } - - @Override - public Response xgroupCreateConsumer(byte[] key, byte[] groupName, byte[] consumerName) { - return appendCommand(commandObjects.xgroupCreateConsumer(key, groupName, consumerName)); - } - - @Override - public Response xgroupDelConsumer(byte[] key, byte[] groupName, byte[] consumerName) { - return appendCommand(commandObjects.xgroupDelConsumer(key, groupName, consumerName)); - } - - @Override - public Response xdel(byte[] key, byte[]... ids) { - return appendCommand(commandObjects.xdel(key, ids)); - } - - @Override - public Response xtrim(byte[] key, long maxLen, boolean approximateLength) { - return appendCommand(commandObjects.xtrim(key, maxLen, approximateLength)); - } - - @Override - public Response xtrim(byte[] key, XTrimParams params) { - return appendCommand(commandObjects.xtrim(key, params)); - } - - @Override - public Response xpending(byte[] key, byte[] groupName) { - return appendCommand(commandObjects.xpending(key, groupName)); - } - - @Override - public Response> xpending(byte[] key, byte[] groupName, XPendingParams params) { - return appendCommand(commandObjects.xpending(key, groupName, params)); - } - - @Override - public Response> xclaim(byte[] key, byte[] group, byte[] consumerName, long minIdleTime, XClaimParams params, byte[]... ids) { - return appendCommand(commandObjects.xclaim(key, group, consumerName, minIdleTime, params, ids)); - } - - @Override - public Response> xclaimJustId(byte[] key, byte[] group, byte[] consumerName, long minIdleTime, XClaimParams params, byte[]... ids) { - return appendCommand(commandObjects.xclaimJustId(key, group, consumerName, minIdleTime, params, ids)); - } - - @Override - public Response> xautoclaim(byte[] key, byte[] groupName, byte[] consumerName, long minIdleTime, byte[] start, XAutoClaimParams params) { - return appendCommand(commandObjects.xautoclaim(key, groupName, consumerName, minIdleTime, start, params)); - } - - @Override - public Response> xautoclaimJustId(byte[] key, byte[] groupName, byte[] consumerName, long minIdleTime, byte[] start, XAutoClaimParams params) { - return appendCommand(commandObjects.xautoclaimJustId(key, groupName, consumerName, minIdleTime, start, params)); - } - - @Override - public Response xinfoStream(byte[] key) { - return appendCommand(commandObjects.xinfoStream(key)); - } - - @Override - public Response xinfoStreamFull(byte[] key) { - return appendCommand(commandObjects.xinfoStreamFull(key)); - } - - @Override - public Response xinfoStreamFull(byte[] key, int count) { - return appendCommand(commandObjects.xinfoStreamFull(key, count)); - } - - @Override - public Response> xinfoGroups(byte[] key) { - return appendCommand(commandObjects.xinfoGroups(key)); - } - - @Override - public Response> xinfoConsumers(byte[] key, byte[] group) { - return appendCommand(commandObjects.xinfoConsumers(key, group)); - } - - @Override - public Response> xread(XReadParams xReadParams, Map.Entry... streams) { - return appendCommand(commandObjects.xread(xReadParams, streams)); - } - - @Override - public Response> xreadGroup(byte[] groupName, byte[] consumer, XReadGroupParams xReadGroupParams, Map.Entry... streams) { - return appendCommand(commandObjects.xreadGroup(groupName, consumer, xReadGroupParams, streams)); - } - - @Override - public Response set(byte[] key, byte[] value) { - return appendCommand(commandObjects.set(key, value)); - } - - @Override - public Response set(byte[] key, byte[] value, SetParams params) { - return appendCommand(commandObjects.set(key, value, params)); - } - - @Override - public Response get(byte[] key) { - return appendCommand(commandObjects.get(key)); - } - - @Override - public Response setGet(byte[] key, byte[] value, SetParams params) { - return appendCommand(commandObjects.setGet(key, value, params)); - } - - @Override - public Response getDel(byte[] key) { - return appendCommand(commandObjects.getDel(key)); - } - - @Override - public Response getEx(byte[] key, GetExParams params) { - return appendCommand(commandObjects.getEx(key, params)); - } - - @Override - public Response setbit(byte[] key, long offset, boolean value) { - return appendCommand(commandObjects.setbit(key, offset, value)); - } - - @Override - public Response getbit(byte[] key, long offset) { - return appendCommand(commandObjects.getbit(key, offset)); - } - - @Override - public Response setrange(byte[] key, long offset, byte[] value) { - return appendCommand(commandObjects.setrange(key, offset, value)); - } - - @Override - public Response getrange(byte[] key, long startOffset, long endOffset) { - return appendCommand(commandObjects.getrange(key, startOffset, endOffset)); - } - - @Override - public Response getSet(byte[] key, byte[] value) { - return appendCommand(commandObjects.getSet(key, value)); - } - - @Override - public Response setnx(byte[] key, byte[] value) { - return appendCommand(commandObjects.setnx(key, value)); - } - - @Override - public Response setex(byte[] key, long seconds, byte[] value) { - return appendCommand(commandObjects.setex(key, seconds, value)); - } - - @Override - public Response psetex(byte[] key, long milliseconds, byte[] value) { - return appendCommand(commandObjects.psetex(key, milliseconds, value)); - } - - @Override - public Response> mget(byte[]... keys) { - return appendCommand(commandObjects.mget(keys)); - } - - @Override - public Response mset(byte[]... keysvalues) { - return appendCommand(commandObjects.mset(keysvalues)); - } - - @Override - public Response msetnx(byte[]... keysvalues) { - return appendCommand(commandObjects.msetnx(keysvalues)); - } - - @Override - public Response incr(byte[] key) { - return appendCommand(commandObjects.incr(key)); - } - - @Override - public Response incrBy(byte[] key, long increment) { - return appendCommand(commandObjects.incrBy(key, increment)); - } - - @Override - public Response incrByFloat(byte[] key, double increment) { - return appendCommand(commandObjects.incrByFloat(key, increment)); - } - - @Override - public Response decr(byte[] key) { - return appendCommand(commandObjects.decr(key)); - } - - @Override - public Response decrBy(byte[] key, long decrement) { - return appendCommand(commandObjects.decrBy(key, decrement)); - } - - @Override - public Response append(byte[] key, byte[] value) { - return appendCommand(commandObjects.append(key, value)); - } - - @Override - public Response substr(byte[] key, int start, int end) { - return appendCommand(commandObjects.substr(key, start, end)); - } - - @Override - public Response strlen(byte[] key) { - return appendCommand(commandObjects.strlen(key)); - } - - @Override - public Response bitcount(byte[] key) { - return appendCommand(commandObjects.bitcount(key)); - } - - @Override - public Response bitcount(byte[] key, long start, long end) { - return appendCommand(commandObjects.bitcount(key, start, end)); - } - - @Override - public Response bitcount(byte[] key, long start, long end, BitCountOption option) { - return appendCommand(commandObjects.bitcount(key, start, end, option)); - } - - @Override - public Response bitpos(byte[] key, boolean value) { - return appendCommand(commandObjects.bitpos(key, value)); - } - - @Override - public Response bitpos(byte[] key, boolean value, BitPosParams params) { - return appendCommand(commandObjects.bitpos(key, value, params)); - } - - @Override - public Response> bitfield(byte[] key, byte[]... arguments) { - return appendCommand(commandObjects.bitfield(key, arguments)); - } - - @Override - public Response> bitfieldReadonly(byte[] key, byte[]... arguments) { - return appendCommand(commandObjects.bitfieldReadonly(key, arguments)); - } - - @Override - public Response bitop(BitOP op, byte[] destKey, byte[]... srcKeys) { - return appendCommand(commandObjects.bitop(op, destKey, srcKeys)); - } - - // RediSearch commands - @Override - public Response ftCreate(String indexName, IndexOptions indexOptions, Schema schema) { - return appendCommand(commandObjects.ftCreate(indexName, indexOptions, schema)); - } - - @Override - public Response ftCreate(String indexName, FTCreateParams createParams, Iterable schemaFields) { - return appendCommand(commandObjects.ftCreate(indexName, createParams, schemaFields)); - } - - @Override - public Response ftAlter(String indexName, Schema schema) { - return appendCommand(commandObjects.ftAlter(indexName, schema)); - } - - @Override - public Response ftAlter(String indexName, Iterable schemaFields) { - return appendCommand(commandObjects.ftAlter(indexName, schemaFields)); - } - - @Override - public Response ftSearch(String indexName, String query) { - return appendCommand(commandObjects.ftSearch(indexName, query)); - } - - @Override - public Response ftSearch(String indexName, String query, FTSearchParams searchParams) { - return appendCommand(commandObjects.ftSearch(indexName, query, searchParams)); - } - - @Override - public Response ftSearch(String indexName, Query query) { - return appendCommand(commandObjects.ftSearch(indexName, query)); - } - - @Override - @Deprecated - public Response ftSearch(byte[] indexName, Query query) { - return appendCommand(commandObjects.ftSearch(indexName, query)); - } - - @Override - public Response ftExplain(String indexName, Query query) { - return appendCommand(commandObjects.ftExplain(indexName, query)); - } - - @Override - public Response> ftExplainCLI(String indexName, Query query) { - return appendCommand(commandObjects.ftExplainCLI(indexName, query)); - } - - @Override - public Response ftAggregate(String indexName, AggregationBuilder aggr) { - return appendCommand(commandObjects.ftAggregate(indexName, aggr)); - } - - @Override - public Response ftSynUpdate(String indexName, String synonymGroupId, String... terms) { - return appendCommand(commandObjects.ftSynUpdate(indexName, synonymGroupId, terms)); - } - - @Override - public Response>> ftSynDump(String indexName) { - return appendCommand(commandObjects.ftSynDump(indexName)); - } - - @Override - public Response ftDictAdd(String dictionary, String... terms) { - return appendCommand(commandObjects.ftDictAdd(dictionary, terms)); - } - - @Override - public Response ftDictDel(String dictionary, String... terms) { - return appendCommand(commandObjects.ftDictDel(dictionary, terms)); - } - - @Override - public Response> ftDictDump(String dictionary) { - return appendCommand(commandObjects.ftDictDump(dictionary)); - } - - @Override - public Response ftDictAddBySampleKey(String indexName, String dictionary, String... terms) { - return appendCommand(commandObjects.ftDictAddBySampleKey(indexName, dictionary, terms)); - } - - @Override - public Response ftDictDelBySampleKey(String indexName, String dictionary, String... terms) { - return appendCommand(commandObjects.ftDictDelBySampleKey(indexName, dictionary, terms)); - } - - @Override - public Response> ftDictDumpBySampleKey(String indexName, String dictionary) { - return appendCommand(commandObjects.ftDictDumpBySampleKey(indexName, dictionary)); - } - - @Override - public Response>> ftSpellCheck(String index, String query) { - return appendCommand(commandObjects.ftSpellCheck(index, query)); - } - - @Override - public Response>> ftSpellCheck(String index, String query, FTSpellCheckParams spellCheckParams) { - return appendCommand(commandObjects.ftSpellCheck(index, query, spellCheckParams)); - } - - @Override - public Response> ftInfo(String indexName) { - return appendCommand(commandObjects.ftInfo(indexName)); - } - - @Override - public Response> ftTagVals(String indexName, String fieldName) { - return appendCommand(commandObjects.ftTagVals(indexName, fieldName)); - } - - @Override - public Response> ftConfigGet(String option) { - return appendCommand(commandObjects.ftConfigGet(option)); - } - - @Override - public Response> ftConfigGet(String indexName, String option) { - return appendCommand(commandObjects.ftConfigGet(indexName, option)); - } - - @Override - public Response ftConfigSet(String option, String value) { - return appendCommand(commandObjects.ftConfigSet(option, value)); - } - - @Override - public Response ftConfigSet(String indexName, String option, String value) { - return appendCommand(commandObjects.ftConfigSet(indexName, option, value)); - } - - @Override - public Response ftSugAdd(String key, String string, double score) { - return appendCommand(commandObjects.ftSugAdd(key, string, score)); - } - - @Override - public Response ftSugAddIncr(String key, String string, double score) { - return appendCommand(commandObjects.ftSugAddIncr(key, string, score)); - } - - @Override - public Response> ftSugGet(String key, String prefix) { - return appendCommand(commandObjects.ftSugGet(key, prefix)); - } - - @Override - public Response> ftSugGet(String key, String prefix, boolean fuzzy, int max) { - return appendCommand(commandObjects.ftSugGet(key, prefix, fuzzy, max)); - } - - @Override - public Response> ftSugGetWithScores(String key, String prefix) { - return appendCommand(commandObjects.ftSugGetWithScores(key, prefix)); - } - - @Override - public Response> ftSugGetWithScores(String key, String prefix, boolean fuzzy, int max) { - return appendCommand(commandObjects.ftSugGetWithScores(key, prefix, fuzzy, max)); - } - - @Override - public Response ftSugDel(String key, String string) { - return appendCommand(commandObjects.ftSugDel(key, string)); - } - - @Override - public Response ftSugLen(String key) { - return appendCommand(commandObjects.ftSugLen(key)); - } - // RediSearch commands - - // RedisJSON commands - @Override - public Response lcs(byte[] keyA, byte[] keyB, LCSParams params) { - return appendCommand(commandObjects.lcs(keyA, keyB, params)); - } - - - @Override - public Response jsonSet(String key, Path2 path, Object object) { - return appendCommand(commandObjects.jsonSet(key, path, object)); - } - - @Override - public Response jsonSetWithEscape(String key, Path2 path, Object object) { - return appendCommand(commandObjects.jsonSetWithEscape(key, path, object)); - } - - @Override - public Response jsonSet(String key, Path path, Object object) { - return appendCommand(commandObjects.jsonSet(key, path, object)); - } - - @Override - public Response jsonSet(String key, Path2 path, Object object, JsonSetParams params) { - return appendCommand(commandObjects.jsonSet(key, path, object, params)); - } - - @Override - public Response jsonSetWithEscape(String key, Path2 path, Object object, JsonSetParams params) { - return appendCommand(commandObjects.jsonSetWithEscape(key, path, object, params)); - } - - @Override - public Response jsonSet(String key, Path path, Object object, JsonSetParams params) { - return appendCommand(commandObjects.jsonSet(key, path, object, params)); - } - - @Override - public Response jsonMerge(String key, Path2 path, Object object) { - return appendCommand(commandObjects.jsonMerge(key, path, object)); - } - - @Override - public Response jsonMerge(String key, Path path, Object object) { - return appendCommand(commandObjects.jsonMerge(key, path, object)); - } - - @Override - public Response jsonGet(String key) { - return appendCommand(commandObjects.jsonGet(key)); - } - - @Override - public Response jsonGet(String key, Class clazz) { - return appendCommand(commandObjects.jsonGet(key, clazz)); - } - - @Override - public Response jsonGet(String key, Path2... paths) { - return appendCommand(commandObjects.jsonGet(key, paths)); - } - - @Override - public Response jsonGet(String key, Path... paths) { - return appendCommand(commandObjects.jsonGet(key, paths)); - } - - @Override - public Response jsonGet(String key, Class clazz, Path... paths) { - return appendCommand(commandObjects.jsonGet(key, clazz, paths)); - } - - @Override - public Response> jsonMGet(Path2 path, String... keys) { - return appendCommand(commandObjects.jsonMGet(path, keys)); - } - - @Override - public Response> jsonMGet(Path path, Class clazz, String... keys) { - return appendCommand(commandObjects.jsonMGet(path, clazz, keys)); - } - - @Override - public Response jsonDel(String key) { - return appendCommand(commandObjects.jsonDel(key)); - } - - @Override - public Response jsonDel(String key, Path2 path) { - return appendCommand(commandObjects.jsonDel(key, path)); - } - - @Override - public Response jsonDel(String key, Path path) { - return appendCommand(commandObjects.jsonDel(key, path)); - } - - @Override - public Response jsonClear(String key) { - return appendCommand(commandObjects.jsonClear(key)); - } - - @Override - public Response jsonClear(String key, Path2 path) { - return appendCommand(commandObjects.jsonClear(key, path)); - } - - @Override - public Response jsonClear(String key, Path path) { - return appendCommand(commandObjects.jsonClear(key, path)); - } - - @Override - public Response> jsonToggle(String key, Path2 path) { - return appendCommand(commandObjects.jsonToggle(key, path)); - } - - @Override - public Response jsonToggle(String key, Path path) { - return appendCommand(commandObjects.jsonToggle(key, path)); - } - - @Override - public Response> jsonType(String key) { - return appendCommand(commandObjects.jsonType(key)); - } - - @Override - public Response>> jsonType(String key, Path2 path) { - return appendCommand(commandObjects.jsonType(key, path)); - } - - @Override - public Response> jsonType(String key, Path path) { - return appendCommand(commandObjects.jsonType(key, path)); - } - - @Override - public Response jsonStrAppend(String key, Object string) { - return appendCommand(commandObjects.jsonStrAppend(key, string)); - } - - @Override - public Response> jsonStrAppend(String key, Path2 path, Object string) { - return appendCommand(commandObjects.jsonStrAppend(key, path, string)); - } - - @Override - public Response jsonStrAppend(String key, Path path, Object string) { - return appendCommand(commandObjects.jsonStrAppend(key, path, string)); - } - - @Override - public Response jsonStrLen(String key) { - return appendCommand(commandObjects.jsonStrLen(key)); - } - - @Override - public Response> jsonStrLen(String key, Path2 path) { - return appendCommand(commandObjects.jsonStrLen(key, path)); - } - - @Override - public Response jsonStrLen(String key, Path path) { - return appendCommand(commandObjects.jsonStrLen(key, path)); - } - - @Override - public Response jsonNumIncrBy(String key, Path2 path, double value) { - return appendCommand(commandObjects.jsonNumIncrBy(key, path, value)); - } - - @Override - public Response jsonNumIncrBy(String key, Path path, double value) { - return appendCommand(commandObjects.jsonNumIncrBy(key, path, value)); - } - - @Override - public Response> jsonArrAppend(String key, Path2 path, Object... objects) { - return appendCommand(commandObjects.jsonArrAppend(key, path, objects)); - } - - @Override - public Response> jsonArrAppendWithEscape(String key, Path2 path, Object... objects) { - return appendCommand(commandObjects.jsonArrAppendWithEscape(key, path, objects)); - } - - @Override - public Response jsonArrAppend(String key, Path path, Object... objects) { - return appendCommand(commandObjects.jsonArrAppend(key, path, objects)); - } - - @Override - public Response> jsonArrIndex(String key, Path2 path, Object scalar) { - return appendCommand(commandObjects.jsonArrIndex(key, path, scalar)); - } - - @Override - public Response> jsonArrIndexWithEscape(String key, Path2 path, Object scalar) { - return appendCommand(commandObjects.jsonArrIndexWithEscape(key, path, scalar)); - } - - @Override - public Response jsonArrIndex(String key, Path path, Object scalar) { - return appendCommand(commandObjects.jsonArrIndex(key, path, scalar)); - } - - @Override - public Response> jsonArrInsert(String key, Path2 path, int index, Object... objects) { - return appendCommand(commandObjects.jsonArrInsert(key, path, index, objects)); - } - - @Override - public Response> jsonArrInsertWithEscape(String key, Path2 path, int index, Object... objects) { - return appendCommand(commandObjects.jsonArrInsertWithEscape(key, path, index, objects)); - } - - @Override - public Response jsonArrInsert(String key, Path path, int index, Object... pojos) { - return appendCommand(commandObjects.jsonArrInsert(key, path, index, pojos)); - } - - @Override - public Response jsonArrPop(String key) { - return appendCommand(commandObjects.jsonArrPop(key)); - } - - @Override - public Response jsonArrLen(String key, Path path) { - return appendCommand(commandObjects.jsonArrLen(key, path)); - } - - @Override - public Response> jsonArrTrim(String key, Path2 path, int start, int stop) { - return appendCommand(commandObjects.jsonArrTrim(key, path, start, stop)); - } - - @Override - public Response jsonArrTrim(String key, Path path, int start, int stop) { - return appendCommand(commandObjects.jsonArrTrim(key, path, start, stop)); - } - - @Override - public Response jsonArrPop(String key, Class clazz, Path path) { - return appendCommand(commandObjects.jsonArrPop(key, clazz, path)); - } - - @Override - public Response> jsonArrPop(String key, Path2 path, int index) { - return appendCommand(commandObjects.jsonArrPop(key, path, index)); - } - - @Override - public Response jsonArrPop(String key, Path path, int index) { - return appendCommand(commandObjects.jsonArrPop(key, path, index)); - } - - @Override - public Response jsonArrPop(String key, Class clazz, Path path, int index) { - return appendCommand(commandObjects.jsonArrPop(key, clazz, path, index)); - } - - @Override - public Response jsonArrLen(String key) { - return appendCommand(commandObjects.jsonArrLen(key)); - } - - @Override - public Response> jsonArrLen(String key, Path2 path) { - return appendCommand(commandObjects.jsonArrLen(key, path)); - } - - @Override - public Response jsonArrPop(String key, Class clazz) { - return appendCommand(commandObjects.jsonArrPop(key, clazz)); - } - - @Override - public Response> jsonArrPop(String key, Path2 path) { - return appendCommand(commandObjects.jsonArrPop(key, path)); - } - - @Override - public Response jsonArrPop(String key, Path path) { - return appendCommand(commandObjects.jsonArrPop(key, path)); - } - // RedisJSON commands - - // RedisTimeSeries commands - @Override - public Response tsCreate(String key) { - return appendCommand(commandObjects.tsCreate(key)); - } - - @Override - public Response tsCreate(String key, TSCreateParams createParams) { - return appendCommand(commandObjects.tsCreate(key, createParams)); - } - - @Override - public Response tsDel(String key, long fromTimestamp, long toTimestamp) { - return appendCommand(commandObjects.tsDel(key, fromTimestamp, toTimestamp)); - } - - @Override - public Response tsAlter(String key, TSAlterParams alterParams) { - return appendCommand(commandObjects.tsAlter(key, alterParams)); - } - - @Override - public Response tsAdd(String key, double value) { - return appendCommand(commandObjects.tsAdd(key, value)); - } - - @Override - public Response tsAdd(String key, long timestamp, double value) { - return appendCommand(commandObjects.tsAdd(key, timestamp, value)); - } - - @Override - public Response tsAdd(String key, long timestamp, double value, TSCreateParams createParams) { - return appendCommand(commandObjects.tsAdd(key, timestamp, value, createParams)); - } - - @Override - public Response> tsMAdd(Map.Entry... entries) { - return appendCommand(commandObjects.tsMAdd(entries)); - } - - @Override - public Response tsIncrBy(String key, double value) { - return appendCommand(commandObjects.tsIncrBy(key, value)); - } - - @Override - public Response tsIncrBy(String key, double value, long timestamp) { - return appendCommand(commandObjects.tsIncrBy(key, value, timestamp)); - } - - @Override - public Response tsDecrBy(String key, double value) { - return appendCommand(commandObjects.tsDecrBy(key, value)); - } - - @Override - public Response tsDecrBy(String key, double value, long timestamp) { - return appendCommand(commandObjects.tsDecrBy(key, value, timestamp)); - } - - @Override - public Response> tsRange(String key, long fromTimestamp, long toTimestamp) { - return appendCommand(commandObjects.tsRange(key, fromTimestamp, toTimestamp)); - } - - @Override - public Response> tsRange(String key, TSRangeParams rangeParams) { - return appendCommand(commandObjects.tsRange(key, rangeParams)); - } - - @Override - public Response> tsRevRange(String key, long fromTimestamp, long toTimestamp) { - return appendCommand(commandObjects.tsRevRange(key, fromTimestamp, toTimestamp)); - } - - @Override - public Response> tsRevRange(String key, TSRangeParams rangeParams) { - return appendCommand(commandObjects.tsRevRange(key, rangeParams)); - } - - @Override - public Response> tsMRange(long fromTimestamp, long toTimestamp, String... filters) { - return appendCommand(commandObjects.tsMRange(fromTimestamp, toTimestamp, filters)); - } - - @Override - public Response> tsMRange(TSMRangeParams multiRangeParams) { - return appendCommand(commandObjects.tsMRange(multiRangeParams)); - } - - @Override - public Response> tsMRevRange(long fromTimestamp, long toTimestamp, String... filters) { - return appendCommand(commandObjects.tsMRevRange(fromTimestamp, toTimestamp, filters)); - } - - @Override - public Response> tsMRevRange(TSMRangeParams multiRangeParams) { - return appendCommand(commandObjects.tsMRevRange(multiRangeParams)); - } - - @Override - public Response tsGet(String key) { - return appendCommand(commandObjects.tsGet(key)); - } - - @Override - public Response tsGet(String key, TSGetParams getParams) { - return appendCommand(commandObjects.tsGet(key, getParams)); - } - - @Override - public Response> tsMGet(TSMGetParams multiGetParams, String... filters) { - return appendCommand(commandObjects.tsMGet(multiGetParams, filters)); - } - - @Override - public Response tsCreateRule(String sourceKey, String destKey, AggregationType aggregationType, long timeBucket) { - return appendCommand(commandObjects.tsCreateRule(sourceKey, destKey, aggregationType, timeBucket)); - } - - @Override - public Response tsCreateRule(String sourceKey, String destKey, AggregationType aggregationType, long bucketDuration, long alignTimestamp) { - return appendCommand(commandObjects.tsCreateRule(sourceKey, destKey, aggregationType, bucketDuration, alignTimestamp)); - } - - @Override - public Response tsDeleteRule(String sourceKey, String destKey) { - return appendCommand(commandObjects.tsDeleteRule(sourceKey, destKey)); - } - - @Override - public Response> tsQueryIndex(String... filters) { - return appendCommand(commandObjects.tsQueryIndex(filters)); - } - // RedisTimeSeries commands - - // RedisBloom commands - @Override - public Response bfReserve(String key, double errorRate, long capacity) { - return appendCommand(commandObjects.bfReserve(key, errorRate, capacity)); - } - - @Override - public Response bfReserve(String key, double errorRate, long capacity, BFReserveParams reserveParams) { - return appendCommand(commandObjects.bfReserve(key, errorRate, capacity, reserveParams)); - } - - @Override - public Response bfAdd(String key, String item) { - return appendCommand(commandObjects.bfAdd(key, item)); - } - - @Override - public Response> bfMAdd(String key, String... items) { - return appendCommand(commandObjects.bfMAdd(key, items)); - } - - @Override - public Response> bfInsert(String key, String... items) { - return appendCommand(commandObjects.bfInsert(key, items)); - } - - @Override - public Response> bfInsert(String key, BFInsertParams insertParams, String... items) { - return appendCommand(commandObjects.bfInsert(key, insertParams, items)); - } - - @Override - public Response bfExists(String key, String item) { - return appendCommand(commandObjects.bfExists(key, item)); - } - - @Override - public Response> bfMExists(String key, String... items) { - return appendCommand(commandObjects.bfMExists(key, items)); - } - - @Override - public Response> bfScanDump(String key, long iterator) { - return appendCommand(commandObjects.bfScanDump(key, iterator)); - } - - @Override - public Response bfLoadChunk(String key, long iterator, byte[] data) { - return appendCommand(commandObjects.bfLoadChunk(key, iterator, data)); - } - - @Override - public Response bfCard(String key) { - return appendCommand(commandObjects.bfCard(key)); - } - - @Override - public Response> bfInfo(String key) { - return appendCommand(commandObjects.bfInfo(key)); - } - - @Override - public Response cfReserve(String key, long capacity) { - return appendCommand(commandObjects.cfReserve(key, capacity)); - } - - @Override - public Response cfReserve(String key, long capacity, CFReserveParams reserveParams) { - return appendCommand(commandObjects.cfReserve(key, capacity, reserveParams)); - } - - @Override - public Response cfAdd(String key, String item) { - return appendCommand(commandObjects.cfAdd(key, item)); - } - - @Override - public Response cfAddNx(String key, String item) { - return appendCommand(commandObjects.cfAddNx(key, item)); - } - - @Override - public Response> cfInsert(String key, String... items) { - return appendCommand(commandObjects.cfInsert(key, items)); - } - - @Override - public Response> cfInsert(String key, CFInsertParams insertParams, String... items) { - return appendCommand(commandObjects.cfInsert(key, insertParams, items)); - } - - @Override - public Response> cfInsertNx(String key, String... items) { - return appendCommand(commandObjects.cfInsertNx(key, items)); - } - - @Override - public Response> cfInsertNx(String key, CFInsertParams insertParams, String... items) { - return appendCommand(commandObjects.cfInsertNx(key, insertParams, items)); - } - - @Override - public Response cfExists(String key, String item) { - return appendCommand(commandObjects.cfExists(key, item)); - } - - @Override - public Response cfDel(String key, String item) { - return appendCommand(commandObjects.cfDel(key, item)); - } - - @Override - public Response cfCount(String key, String item) { - return appendCommand(commandObjects.cfCount(key, item)); - } - - @Override - public Response> cfScanDump(String key, long iterator) { - return appendCommand(commandObjects.cfScanDump(key, iterator)); - } - - @Override - public Response cfLoadChunk(String key, long iterator, byte[] data) { - return appendCommand(commandObjects.cfLoadChunk(key, iterator, data)); - } - - @Override - public Response> cfInfo(String key) { - return appendCommand(commandObjects.cfInfo(key)); - } - - @Override - public Response cmsInitByDim(String key, long width, long depth) { - return appendCommand(commandObjects.cmsInitByDim(key, width, depth)); - } - - @Override - public Response cmsInitByProb(String key, double error, double probability) { - return appendCommand(commandObjects.cmsInitByProb(key, error, probability)); - } - - @Override - public Response> cmsIncrBy(String key, Map itemIncrements) { - return appendCommand(commandObjects.cmsIncrBy(key, itemIncrements)); - } - - @Override - public Response> cmsQuery(String key, String... items) { - return appendCommand(commandObjects.cmsQuery(key, items)); - } - - @Override - public Response cmsMerge(String destKey, String... keys) { - return appendCommand(commandObjects.cmsMerge(destKey, keys)); - } - - @Override - public Response cmsMerge(String destKey, Map keysAndWeights) { - return appendCommand(commandObjects.cmsMerge(destKey, keysAndWeights)); - } - - @Override - public Response> cmsInfo(String key) { - return appendCommand(commandObjects.cmsInfo(key)); - } - - @Override - public Response topkReserve(String key, long topk) { - return appendCommand(commandObjects.topkReserve(key, topk)); - } - - @Override - public Response topkReserve(String key, long topk, long width, long depth, double decay) { - return appendCommand(commandObjects.topkReserve(key, topk, width, depth, decay)); - } - - @Override - public Response> topkAdd(String key, String... items) { - return appendCommand(commandObjects.topkAdd(key, items)); - } - - @Override - public Response> topkIncrBy(String key, Map itemIncrements) { - return appendCommand(commandObjects.topkIncrBy(key, itemIncrements)); - } - - @Override - public Response> topkQuery(String key, String... items) { - return appendCommand(commandObjects.topkQuery(key, items)); - } - - @Override - public Response> topkList(String key) { - return appendCommand(commandObjects.topkList(key)); - } - - @Override - public Response> topkListWithCount(String key) { - return appendCommand(commandObjects.topkListWithCount(key)); - } - - @Override - public Response> topkInfo(String key) { - return appendCommand(commandObjects.topkInfo(key)); - } - - @Override - public Response tdigestCreate(String key) { - return appendCommand(commandObjects.tdigestCreate(key)); - } - - @Override - public Response tdigestCreate(String key, int compression) { - return appendCommand(commandObjects.tdigestCreate(key, compression)); - } - - @Override - public Response tdigestReset(String key) { - return appendCommand(commandObjects.tdigestReset(key)); - } - - @Override - public Response tdigestMerge(String destinationKey, String... sourceKeys) { - return appendCommand(commandObjects.tdigestMerge(destinationKey, sourceKeys)); - } - - @Override - public Response tdigestMerge(TDigestMergeParams mergeParams, String destinationKey, String... sourceKeys) { - return appendCommand(commandObjects.tdigestMerge(mergeParams, destinationKey, sourceKeys)); - } - - @Override - public Response> tdigestInfo(String key) { - return appendCommand(commandObjects.tdigestInfo(key)); - } - - @Override - public Response tdigestAdd(String key, double... values) { - return appendCommand(commandObjects.tdigestAdd(key, values)); - } - - @Override - public Response> tdigestCDF(String key, double... values) { - return appendCommand(commandObjects.tdigestCDF(key, values)); - } - - @Override - public Response> tdigestQuantile(String key, double... quantiles) { - return appendCommand(commandObjects.tdigestQuantile(key, quantiles)); - } - - @Override - public Response tdigestMin(String key) { - return appendCommand(commandObjects.tdigestMin(key)); - } - - @Override - public Response tdigestMax(String key) { - return appendCommand(commandObjects.tdigestMax(key)); - } - - @Override - public Response tdigestTrimmedMean(String key, double lowCutQuantile, double highCutQuantile) { - return appendCommand(commandObjects.tdigestTrimmedMean(key, lowCutQuantile, highCutQuantile)); - } - - @Override - public Response> tdigestRank(String key, double... values) { - return appendCommand(commandObjects.tdigestRank(key, values)); - } - - @Override - public Response> tdigestRevRank(String key, double... values) { - return appendCommand(commandObjects.tdigestRevRank(key, values)); - } - - @Override - public Response> tdigestByRank(String key, long... ranks) { - return appendCommand(commandObjects.tdigestByRank(key, ranks)); - } - - @Override - public Response> tdigestByRevRank(String key, long... ranks) { - return appendCommand(commandObjects.tdigestByRevRank(key, ranks)); - } - // RedisBloom commands - - // RedisGraph commands - @Override - public Response graphQuery(String name, String query) { - return appendCommand(graphCommandObjects.graphQuery(name, query)); - } - - @Override - public Response graphReadonlyQuery(String name, String query) { - return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query)); - } - - @Override - public Response graphQuery(String name, String query, long timeout) { - return appendCommand(graphCommandObjects.graphQuery(name, query, timeout)); - } - - @Override - public Response graphReadonlyQuery(String name, String query, long timeout) { - return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query, timeout)); - } - - @Override - public Response graphQuery(String name, String query, Map params) { - return appendCommand(graphCommandObjects.graphQuery(name, query, params)); - } - - @Override - public Response graphReadonlyQuery(String name, String query, Map params) { - return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query, params)); - } - - @Override - public Response graphQuery(String name, String query, Map params, long timeout) { - return appendCommand(graphCommandObjects.graphQuery(name, query, params, timeout)); - } - - @Override - public Response graphReadonlyQuery(String name, String query, Map params, long timeout) { - return appendCommand(graphCommandObjects.graphReadonlyQuery(name, query, params, timeout)); - } - - @Override - public Response graphDelete(String name) { - return appendCommand(graphCommandObjects.graphDelete(name)); - } - - @Override - public Response> graphProfile(String graphName, String query) { - return appendCommand(commandObjects.graphProfile(graphName, query)); - } - // RedisGraph commands - - public Response waitReplicas(int replicas, long timeout) { - return appendCommand(commandObjects.waitReplicas(replicas, timeout)); - } - - public Response sendCommand(ProtocolCommand cmd, String... args) { - return sendCommand(new CommandArguments(cmd).addObjects((Object[]) args)); - } - - public Response sendCommand(ProtocolCommand cmd, byte[]... args) { - return sendCommand(new CommandArguments(cmd).addObjects((Object[]) args)); - } - - public Response sendCommand(CommandArguments args) { - return executeCommand(new CommandObject<>(args, BuilderFactory.RAW_OBJECT)); - } - - public Response executeCommand(CommandObject command) { - return appendCommand(command); + protected TransactionBase() { + super(); } - public void setJsonObjectMapper(JsonObjectMapper jsonObjectMapper) { - this.commandObjects.setJsonObjectMapper(jsonObjectMapper); + protected TransactionBase(CommandObjects commandObjects) { + super(commandObjects); } } diff --git a/src/main/java/redis/clients/jedis/UnifiedJedis.java b/src/main/java/redis/clients/jedis/UnifiedJedis.java index 86758bd421..a43ffc1090 100644 --- a/src/main/java/redis/clients/jedis/UnifiedJedis.java +++ b/src/main/java/redis/clients/jedis/UnifiedJedis.java @@ -19,12 +19,18 @@ import redis.clients.jedis.commands.RedisModuleCommands; import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.executors.*; +import redis.clients.jedis.gears.TFunctionListParams; +import redis.clients.jedis.gears.TFunctionLoadParams; +import redis.clients.jedis.gears.resps.GearsLibraryInfo; import redis.clients.jedis.graph.GraphCommandObjects; import redis.clients.jedis.graph.ResultSet; import redis.clients.jedis.json.JsonSetParams; import redis.clients.jedis.json.Path; import redis.clients.jedis.json.Path2; import redis.clients.jedis.json.JsonObjectMapper; +import redis.clients.jedis.mcf.CircuitBreakerCommandExecutor; +import redis.clients.jedis.mcf.MultiClusterPipeline; +import redis.clients.jedis.mcf.MultiClusterTransaction; import redis.clients.jedis.params.*; import redis.clients.jedis.providers.*; import redis.clients.jedis.resps.*; @@ -54,8 +60,7 @@ public UnifiedJedis() { } public UnifiedJedis(HostAndPort hostAndPort) { -// this(new Connection(hostAndPort)); - this(new PooledConnectionProvider(hostAndPort)); + this(new PooledConnectionProvider(hostAndPort), (RedisProtocol) null); } public UnifiedJedis(final String url) { @@ -83,27 +88,15 @@ public UnifiedJedis(final URI uri, JedisClientConfig config) { } public UnifiedJedis(HostAndPort hostAndPort, JedisClientConfig clientConfig) { -// this(new Connection(hostAndPort, clientConfig)); - this(new PooledConnectionProvider(hostAndPort, clientConfig)); - RedisProtocol proto = clientConfig.getRedisProtocol(); - if (proto != null) commandObjects.setProtocol(proto); + this(new PooledConnectionProvider(hostAndPort, clientConfig), clientConfig.getRedisProtocol()); } public UnifiedJedis(ConnectionProvider provider) { - this.provider = provider; - this.executor = new DefaultCommandExecutor(provider); - this.commandObjects = new CommandObjects(); - this.graphCommandObjects = new GraphCommandObjects(this); - this.graphCommandObjects.setBaseCommandArgumentsCreator((comm) -> this.commandObjects.commandArguments(comm)); - try (Connection conn = this.provider.getConnection()) { - if (conn != null) { - RedisProtocol proto = conn.getRedisProtocol(); - if (proto != null) commandObjects.setProtocol(proto); - } - //} catch (JedisAccessControlException ace) { - } catch (JedisException je) { // TODO: use specific exception(s) - // use default protocol - } + this(new DefaultCommandExecutor(provider), provider); + } + + protected UnifiedJedis(ConnectionProvider provider, RedisProtocol protocol) { + this(new DefaultCommandExecutor(provider), provider, new CommandObjects(), protocol); } /** @@ -136,37 +129,40 @@ public UnifiedJedis(Connection connection) { this.provider = null; this.executor = new SimpleCommandExecutor(connection); this.commandObjects = new CommandObjects(); - this.graphCommandObjects = new GraphCommandObjects(this); RedisProtocol proto = connection.getRedisProtocol(); - if (proto == RedisProtocol.RESP3) this.commandObjects.setProtocol(proto); + if (proto != null) this.commandObjects.setProtocol(proto); + this.graphCommandObjects = new GraphCommandObjects(this); } + @Deprecated public UnifiedJedis(Set jedisClusterNodes, JedisClientConfig clientConfig, int maxAttempts) { - this(new ClusterConnectionProvider(jedisClusterNodes, clientConfig), maxAttempts, - Duration.ofMillis(maxAttempts * clientConfig.getSocketTimeoutMillis())); - RedisProtocol proto = clientConfig.getRedisProtocol(); - if (proto != null) commandObjects.setProtocol(proto); + this(jedisClusterNodes, clientConfig, maxAttempts, Duration.ofMillis(maxAttempts * clientConfig.getSocketTimeoutMillis())); } - public UnifiedJedis(Set jedisClusterNodes, JedisClientConfig clientConfig, int maxAttempts, Duration maxTotalRetriesDuration) { - this(new ClusterConnectionProvider(jedisClusterNodes, clientConfig), maxAttempts, maxTotalRetriesDuration); - RedisProtocol proto = clientConfig.getRedisProtocol(); - if (proto != null) commandObjects.setProtocol(proto); + @Deprecated + public UnifiedJedis(Set jedisClusterNodes, JedisClientConfig clientConfig, int maxAttempts, + Duration maxTotalRetriesDuration) { + this(new ClusterConnectionProvider(jedisClusterNodes, clientConfig), maxAttempts, maxTotalRetriesDuration, + clientConfig.getRedisProtocol()); } + @Deprecated public UnifiedJedis(Set jedisClusterNodes, JedisClientConfig clientConfig, GenericObjectPoolConfig poolConfig, int maxAttempts, Duration maxTotalRetriesDuration) { - this(new ClusterConnectionProvider(jedisClusterNodes, clientConfig, poolConfig), maxAttempts, maxTotalRetriesDuration); - RedisProtocol proto = clientConfig.getRedisProtocol(); - if (proto != null) commandObjects.setProtocol(proto); + this(new ClusterConnectionProvider(jedisClusterNodes, clientConfig, poolConfig), maxAttempts, + maxTotalRetriesDuration, clientConfig.getRedisProtocol()); } + // Uses a fetched connection to process protocol. Should be avoided if possible. public UnifiedJedis(ClusterConnectionProvider provider, int maxAttempts, Duration maxTotalRetriesDuration) { - this.provider = provider; - this.executor = new ClusterCommandExecutor(provider, maxAttempts, maxTotalRetriesDuration); - this.commandObjects = new ClusterCommandObjects(); - this.graphCommandObjects = new GraphCommandObjects(this); - this.graphCommandObjects.setBaseCommandArgumentsCreator((comm) -> this.commandObjects.commandArguments(comm)); + this(new ClusterCommandExecutor(provider, maxAttempts, maxTotalRetriesDuration), provider, + new ClusterCommandObjects()); + } + + protected UnifiedJedis(ClusterConnectionProvider provider, int maxAttempts, Duration maxTotalRetriesDuration, + RedisProtocol protocol) { + this(new ClusterCommandExecutor(provider, maxAttempts, maxTotalRetriesDuration), provider, + new ClusterCommandObjects(), protocol); } /** @@ -174,11 +170,7 @@ public UnifiedJedis(ClusterConnectionProvider provider, int maxAttempts, Duratio */ @Deprecated public UnifiedJedis(ShardedConnectionProvider provider) { - this.provider = provider; - this.executor = new DefaultCommandExecutor(provider); - this.commandObjects = new ShardedCommandObjects(provider.getHashingAlgo()); - this.graphCommandObjects = new GraphCommandObjects(this); - this.graphCommandObjects.setBaseCommandArgumentsCreator((comm) -> this.commandObjects.commandArguments(comm)); + this(new DefaultCommandExecutor(provider), provider, new ShardedCommandObjects(provider.getHashingAlgo())); } /** @@ -186,19 +178,11 @@ public UnifiedJedis(ShardedConnectionProvider provider) { */ @Deprecated public UnifiedJedis(ShardedConnectionProvider provider, Pattern tagPattern) { - this.provider = provider; - this.executor = new DefaultCommandExecutor(provider); - this.commandObjects = new ShardedCommandObjects(provider.getHashingAlgo(), tagPattern); - this.graphCommandObjects = new GraphCommandObjects(this); - this.graphCommandObjects.setBaseCommandArgumentsCreator((comm) -> this.commandObjects.commandArguments(comm)); + this(new DefaultCommandExecutor(provider), provider, new ShardedCommandObjects(provider.getHashingAlgo(), tagPattern)); } public UnifiedJedis(ConnectionProvider provider, int maxAttempts, Duration maxTotalRetriesDuration) { - this.provider = provider; - this.executor = new RetryableCommandExecutor(provider, maxAttempts, maxTotalRetriesDuration); - this.commandObjects = new CommandObjects(); - this.graphCommandObjects = new GraphCommandObjects(this); - this.graphCommandObjects.setBaseCommandArgumentsCreator((comm) -> this.commandObjects.commandArguments(comm)); + this(new RetryableCommandExecutor(provider, maxAttempts, maxTotalRetriesDuration), provider); } /** @@ -209,11 +193,7 @@ public UnifiedJedis(ConnectionProvider provider, int maxAttempts, Duration maxTo *

*/ public UnifiedJedis(MultiClusterPooledConnectionProvider provider) { - this.provider = provider; - this.executor = new CircuitBreakerCommandExecutor(provider); - this.commandObjects = new CommandObjects(); - this.graphCommandObjects = new GraphCommandObjects(this); - this.graphCommandObjects.setBaseCommandArgumentsCreator((comm) -> this.commandObjects.commandArguments(comm)); + this(new CircuitBreakerCommandExecutor(provider), provider); } /** @@ -223,9 +203,36 @@ public UnifiedJedis(MultiClusterPooledConnectionProvider provider) { * {@link UnifiedJedis#provider} is accessed. */ public UnifiedJedis(CommandExecutor executor) { - this.provider = null; + this(executor, (ConnectionProvider) null); + } + + private UnifiedJedis(CommandExecutor executor, ConnectionProvider provider) { + this(executor, provider, new CommandObjects()); + } + + // Uses a fetched connection to process protocol. Should be avoided if possible. + private UnifiedJedis(CommandExecutor executor, ConnectionProvider provider, CommandObjects commandObjects) { + this(executor, provider, commandObjects, null); + if (this.provider != null) { + try (Connection conn = this.provider.getConnection()) { + if (conn != null) { + RedisProtocol proto = conn.getRedisProtocol(); + if (proto != null) this.commandObjects.setProtocol(proto); + } + } catch (JedisException je) { } + } + } + + private UnifiedJedis(CommandExecutor executor, ConnectionProvider provider, CommandObjects commandObjects, + RedisProtocol protocol) { + this.provider = provider; this.executor = executor; - this.commandObjects = new CommandObjects(); + + this.commandObjects = commandObjects; + if (protocol != null) { + this.commandObjects.setProtocol(protocol); + } + this.graphCommandObjects = new GraphCommandObjects(this); this.graphCommandObjects.setBaseCommandArgumentsCreator((comm) -> this.commandObjects.commandArguments(comm)); } @@ -235,6 +242,7 @@ public void close() { IOUtils.closeQuietly(this.executor); } + @Deprecated protected final void setProtocol(RedisProtocol protocol) { this.protocol = protocol; this.commandObjects.setProtocol(this.protocol); @@ -1541,6 +1549,11 @@ public ScanResult> hscan(String key, String cursor, Sc return executeCommand(commandObjects.hscan(key, cursor, params)); } + @Override + public ScanResult hscanNoValues(String key, String cursor, ScanParams params) { + return executeCommand(commandObjects.hscanNoValues(key, cursor, params)); + } + @Override public long hstrlen(String key, String field) { return executeCommand(commandObjects.hstrlen(key, field)); @@ -1566,6 +1579,11 @@ public ScanResult> hscan(byte[] key, byte[] cursor, Sc return executeCommand(commandObjects.hscan(key, cursor, params)); } + @Override + public ScanResult hscanNoValues(byte[] key, byte[] cursor, ScanParams params) { + return executeCommand(commandObjects.hscanNoValues(key, cursor, params)); + } + @Override public long hstrlen(byte[] key, byte[] field) { return executeCommand(commandObjects.hstrlen(key, field)); @@ -3055,22 +3073,22 @@ public long xlen(byte[] key) { } @Override - public List xrange(byte[] key, byte[] start, byte[] end) { + public List xrange(byte[] key, byte[] start, byte[] end) { return executeCommand(commandObjects.xrange(key, start, end)); } @Override - public List xrange(byte[] key, byte[] start, byte[] end, int count) { + public List xrange(byte[] key, byte[] start, byte[] end, int count) { return executeCommand(commandObjects.xrange(key, start, end, count)); } @Override - public List xrevrange(byte[] key, byte[] end, byte[] start) { + public List xrevrange(byte[] key, byte[] end, byte[] start) { return executeCommand(commandObjects.xrevrange(key, end, start)); } @Override - public List xrevrange(byte[] key, byte[] end, byte[] start, int count) { + public List xrevrange(byte[] key, byte[] end, byte[] start, int count) { return executeCommand(commandObjects.xrevrange(key, end, start, count)); } @@ -3175,12 +3193,12 @@ public List xinfoConsumers(byte[] key, byte[] group) { } @Override - public List xread(XReadParams xReadParams, Map.Entry... streams) { + public List xread(XReadParams xReadParams, Map.Entry... streams) { return executeCommand(commandObjects.xread(xReadParams, streams)); } @Override - public List xreadGroup(byte[] groupName, byte[] consumer, XReadGroupParams xReadGroupParams, Map.Entry... streams) { + public List xreadGroup(byte[] groupName, byte[] consumer, XReadGroupParams xReadGroupParams, Map.Entry... streams) { return executeCommand(commandObjects.xreadGroup(groupName, consumer, xReadGroupParams, streams)); } // Stream commands @@ -3318,12 +3336,12 @@ public List functionListWithCode(String libraryNamePattern) { @Override public String functionLoad(String functionCode) { - return executeCommand(commandObjects.functionLoad(functionCode)); + return checkAndBroadcastCommand(commandObjects.functionLoad(functionCode)); } @Override public String functionLoadReplace(String functionCode) { - return executeCommand(commandObjects.functionLoadReplace(functionCode)); + return checkAndBroadcastCommand(commandObjects.functionLoadReplace(functionCode)); } @Override @@ -3373,12 +3391,12 @@ public List functionListWithCode(final byte[] libraryNamePattern) { @Override public String functionLoad(byte[] functionCode) { - return executeCommand(commandObjects.functionLoad(functionCode)); + return checkAndBroadcastCommand(commandObjects.functionLoad(functionCode)); } @Override public String functionLoadReplace(byte[] functionCode) { - return executeCommand(commandObjects.functionLoadReplace(functionCode)); + return checkAndBroadcastCommand(commandObjects.functionLoadReplace(functionCode)); } @Override @@ -3616,6 +3634,14 @@ public void psubscribe(BinaryJedisPubSub jedisPubSub, final byte[]... patterns) // Random node commands // RediSearch commands + public long hsetObject(String key, String field, Object value) { + return executeCommand(commandObjects.hsetObject(key, field, value)); + } + + public long hsetObject(String key, Map hash) { + return executeCommand(commandObjects.hsetObject(key, hash)); + } + @Override public String ftCreate(String indexName, IndexOptions indexOptions, Schema schema) { return checkAndBroadcastCommand(commandObjects.ftCreate(indexName, indexOptions, schema)); @@ -3636,6 +3662,31 @@ public String ftAlter(String indexName, Iterable schemaFields) { return checkAndBroadcastCommand(commandObjects.ftAlter(indexName, schemaFields)); } + @Override + public String ftAliasAdd(String aliasName, String indexName) { + return checkAndBroadcastCommand(commandObjects.ftAliasAdd(aliasName, indexName)); + } + + @Override + public String ftAliasUpdate(String aliasName, String indexName) { + return checkAndBroadcastCommand(commandObjects.ftAliasUpdate(aliasName, indexName)); + } + + @Override + public String ftAliasDel(String aliasName) { + return checkAndBroadcastCommand(commandObjects.ftAliasDel(aliasName)); + } + + @Override + public String ftDropIndex(String indexName) { + return checkAndBroadcastCommand(commandObjects.ftDropIndex(indexName)); + } + + @Override + public String ftDropIndexDD(String indexName) { + return checkAndBroadcastCommand(commandObjects.ftDropIndexDD(indexName)); + } + @Override public SearchResult ftSearch(String indexName, String query) { return executeCommand(commandObjects.ftSearch(indexName, query)); @@ -3733,16 +3784,6 @@ public Map.Entry> ftProfileSearch(String index return executeCommand(commandObjects.ftProfileSearch(indexName, profileParams, query, searchParams)); } - @Override - public String ftDropIndex(String indexName) { - return checkAndBroadcastCommand(commandObjects.ftDropIndex(indexName)); - } - - @Override - public String ftDropIndexDD(String indexName) { - return checkAndBroadcastCommand(commandObjects.ftDropIndexDD(indexName)); - } - @Override public String ftSynUpdate(String indexName, String synonymGroupId, String... terms) { return executeCommand(commandObjects.ftSynUpdate(indexName, synonymGroupId, terms)); @@ -3803,21 +3844,6 @@ public Set ftTagVals(String indexName, String fieldName) { return executeCommand(commandObjects.ftTagVals(indexName, fieldName)); } - @Override - public String ftAliasAdd(String aliasName, String indexName) { - return checkAndBroadcastCommand(commandObjects.ftAliasAdd(aliasName, indexName)); - } - - @Override - public String ftAliasUpdate(String aliasName, String indexName) { - return checkAndBroadcastCommand(commandObjects.ftAliasUpdate(aliasName, indexName)); - } - - @Override - public String ftAliasDel(String aliasName) { - return checkAndBroadcastCommand(commandObjects.ftAliasDel(aliasName)); - } - @Override public Map ftConfigGet(String option) { return executeCommand(commandObjects.ftConfigGet(option)); @@ -4789,18 +4815,54 @@ public Map graphConfigGet(String configName) { } // RedisGraph commands + // RedisGears commands + @Override + public String tFunctionLoad(String libraryCode, TFunctionLoadParams params) { + return executeCommand(commandObjects.tFunctionLoad(libraryCode, params)); + } + + @Override + public String tFunctionDelete(String libraryName) { + return executeCommand(commandObjects.tFunctionDelete(libraryName)); + } + + @Override + public List tFunctionList(TFunctionListParams params) { + return executeCommand(commandObjects.tFunctionList(params)); + } + + @Override + public Object tFunctionCall(String library, String function, List keys, List args) { + return executeCommand(commandObjects.tFunctionCall(library, function, keys, args)); + } + + @Override + public Object tFunctionCallAsync(String library, String function, List keys, List args) { + return executeCommand(commandObjects.tFunctionCallAsync(library, function, keys, args)); + } + // RedisGears commands + + /** + * @return pipeline object. Use {@link AbstractPipeline} instead of {@link PipelineBase}. + */ public PipelineBase pipelined() { if (provider == null) { throw new IllegalStateException("It is not allowed to create Pipeline from this " + getClass()); + } else if (provider instanceof MultiClusterPooledConnectionProvider) { + return new MultiClusterPipeline((MultiClusterPooledConnectionProvider) provider, commandObjects); + } else { + return new Pipeline(provider.getConnection(), true); } - return new Pipeline(provider.getConnection(), true); } - public Transaction multi() { + public AbstractTransaction multi() { if (provider == null) { throw new IllegalStateException("It is not allowed to create Pipeline from this " + getClass()); + } else if (provider instanceof MultiClusterPooledConnectionProvider) { + return new MultiClusterTransaction((MultiClusterPooledConnectionProvider) provider, true, commandObjects); + } else { + return new Transaction(provider.getConnection(), true, true); } - return new Transaction(provider.getConnection(), true, true); } public Object sendCommand(ProtocolCommand cmd) { diff --git a/src/main/java/redis/clients/jedis/args/LatencyEvent.java b/src/main/java/redis/clients/jedis/args/LatencyEvent.java new file mode 100644 index 0000000000..bd11d6a104 --- /dev/null +++ b/src/main/java/redis/clients/jedis/args/LatencyEvent.java @@ -0,0 +1,24 @@ +package redis.clients.jedis.args; + +import redis.clients.jedis.util.SafeEncoder; + +public enum LatencyEvent implements Rawable { + + ACTIVE_DEFRAG_CYCLE("active-defrag-cycle"), AOF_FSYNC_ALWAYS("aof-fsync-always"), AOF_STAT("aof-stat"), + AOF_REWRITE_DIFF_WRITE("aof-rewrite-diff-write"), AOF_RENAME("aof-rename"), AOF_WRITE("aof-write"), + AOF_WRITE_ACTIVE_CHILD("aof-write-active-child"), AOF_WRITE_ALONE("aof-write-alone"), + AOF_WRITE_PENDING_FSYNC("aof-write-pending-fsync"), COMMAND("command"), EXPIRE_CYCLE("expire-cycle"), + EVICTION_CYCLE("eviction-cycle"), EVICTION_DEL("eviction-del"), FAST_COMMAND("fast-command"), + FORK("fork"), RDB_UNLINK_TEMP_FILE("rdb-unlink-temp-file"); + + private final byte[] raw; + + private LatencyEvent(String s) { + raw = SafeEncoder.encode(s); + } + + @Override + public byte[] getRaw() { + return raw; + } +} diff --git a/src/main/java/redis/clients/jedis/commands/ClientCommands.java b/src/main/java/redis/clients/jedis/commands/ClientCommands.java index edcfbd602e..75bda24a30 100644 --- a/src/main/java/redis/clients/jedis/commands/ClientCommands.java +++ b/src/main/java/redis/clients/jedis/commands/ClientCommands.java @@ -30,10 +30,10 @@ public interface ClientCommands { String clientKill(String ip, int port); /** - * Close a given client connection. + * Close client connections based on certain selection parameters. * - * @param params Connection info will be closed - * @return Close success return OK + * @param params Parameters defining what client connections to close. + * @return The number of client connections that were closed. */ long clientKill(ClientKillParams params); diff --git a/src/main/java/redis/clients/jedis/commands/ClusterCommands.java b/src/main/java/redis/clients/jedis/commands/ClusterCommands.java index da0d3fc8e0..4ad918d12b 100644 --- a/src/main/java/redis/clients/jedis/commands/ClusterCommands.java +++ b/src/main/java/redis/clients/jedis/commands/ClusterCommands.java @@ -5,6 +5,7 @@ import redis.clients.jedis.args.ClusterResetType; import redis.clients.jedis.args.ClusterFailoverOption; +import redis.clients.jedis.resps.ClusterShardInfo; public interface ClusterCommands { @@ -79,8 +80,24 @@ public interface ClusterCommands { String clusterFailover(ClusterFailoverOption failoverOption); + /** + * {@code CLUSTER SLOTS} command is deprecated since Redis 7. + * + * @deprecated Use {@link ClusterCommands#clusterShards()}. + */ + @Deprecated List clusterSlots(); + /** + * {@code CLUSTER SHARDS} returns details about the shards of the cluster. + * This command replaces the {@code CLUSTER SLOTS} command from Redis 7, + * by providing a more efficient and extensible representation of the cluster. + * + * @return a list of shards, with each shard containing two objects, 'slots' and 'nodes'. + * @see CLUSTER SHARDS + */ + List clusterShards(); + String clusterReset(); /** diff --git a/src/main/java/redis/clients/jedis/commands/HashBinaryCommands.java b/src/main/java/redis/clients/jedis/commands/HashBinaryCommands.java index 196f7512a8..15a462c9b7 100644 --- a/src/main/java/redis/clients/jedis/commands/HashBinaryCommands.java +++ b/src/main/java/redis/clients/jedis/commands/HashBinaryCommands.java @@ -49,6 +49,12 @@ default ScanResult> hscan(byte[] key, byte[] cursor) { ScanResult> hscan(byte[] key, byte[] cursor, ScanParams params); + default ScanResult hscanNoValues(byte[] key, byte[] cursor) { + return hscanNoValues(key, cursor, new ScanParams()); + } + + ScanResult hscanNoValues(byte[] key, byte[] cursor, ScanParams params); + long hstrlen(byte[] key, byte[] field); } diff --git a/src/main/java/redis/clients/jedis/commands/HashCommands.java b/src/main/java/redis/clients/jedis/commands/HashCommands.java index d319c4fa39..ef18e34aee 100644 --- a/src/main/java/redis/clients/jedis/commands/HashCommands.java +++ b/src/main/java/redis/clients/jedis/commands/HashCommands.java @@ -49,5 +49,11 @@ default ScanResult> hscan(String key, String cursor) { ScanResult> hscan(String key, String cursor, ScanParams params); + default ScanResult hscanNoValues(String key, String cursor) { + return hscanNoValues(key, cursor, new ScanParams()); + } + + ScanResult hscanNoValues(String key, String cursor, ScanParams params); + long hstrlen(String key, String field); } diff --git a/src/main/java/redis/clients/jedis/commands/HashPipelineBinaryCommands.java b/src/main/java/redis/clients/jedis/commands/HashPipelineBinaryCommands.java index e87dcacdb3..cf104f7a33 100644 --- a/src/main/java/redis/clients/jedis/commands/HashPipelineBinaryCommands.java +++ b/src/main/java/redis/clients/jedis/commands/HashPipelineBinaryCommands.java @@ -50,6 +50,12 @@ default Response>> hscan(byte[] key, byte[] Response>> hscan(byte[] key, byte[] cursor, ScanParams params); + default Response> hscanNoValues(byte[] key, byte[] cursor) { + return hscanNoValues(key, cursor, new ScanParams()); + } + + Response> hscanNoValues(byte[] key, byte[] cursor, ScanParams params); + Response hstrlen(byte[] key, byte[] field); } diff --git a/src/main/java/redis/clients/jedis/commands/HashPipelineCommands.java b/src/main/java/redis/clients/jedis/commands/HashPipelineCommands.java index 3aa256cb78..dabcac4e90 100644 --- a/src/main/java/redis/clients/jedis/commands/HashPipelineCommands.java +++ b/src/main/java/redis/clients/jedis/commands/HashPipelineCommands.java @@ -50,5 +50,11 @@ default Response>> hscan(String key, String Response>> hscan(String key, String cursor, ScanParams params); + default Response> hscanNoValues(String key, String cursor) { + return hscanNoValues(key, cursor, new ScanParams()); + } + + Response> hscanNoValues(String key, String cursor, ScanParams params); + Response hstrlen(String key, String field); } diff --git a/src/main/java/redis/clients/jedis/commands/RedisModuleCommands.java b/src/main/java/redis/clients/jedis/commands/RedisModuleCommands.java index c4b785fc70..5e67838720 100644 --- a/src/main/java/redis/clients/jedis/commands/RedisModuleCommands.java +++ b/src/main/java/redis/clients/jedis/commands/RedisModuleCommands.java @@ -1,6 +1,7 @@ package redis.clients.jedis.commands; import redis.clients.jedis.bloom.commands.RedisBloomCommands; +import redis.clients.jedis.gears.RedisGearsCommands; import redis.clients.jedis.graph.RedisGraphCommands; import redis.clients.jedis.json.commands.RedisJsonCommands; import redis.clients.jedis.search.RediSearchCommands; @@ -11,6 +12,7 @@ public interface RedisModuleCommands extends RedisJsonCommands, RedisTimeSeriesCommands, RedisBloomCommands, - RedisGraphCommands { + RedisGraphCommands, + RedisGearsCommands { } diff --git a/src/main/java/redis/clients/jedis/commands/ServerCommands.java b/src/main/java/redis/clients/jedis/commands/ServerCommands.java index 46f1220407..3aeff1153b 100644 --- a/src/main/java/redis/clients/jedis/commands/ServerCommands.java +++ b/src/main/java/redis/clients/jedis/commands/ServerCommands.java @@ -1,12 +1,18 @@ package redis.clients.jedis.commands; import redis.clients.jedis.args.FlushMode; +import redis.clients.jedis.args.LatencyEvent; import redis.clients.jedis.args.SaveMode; import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.params.LolwutParams; import redis.clients.jedis.params.ShutdownParams; +import redis.clients.jedis.resps.LatencyHistoryInfo; +import redis.clients.jedis.resps.LatencyLatestInfo; import redis.clients.jedis.util.KeyValue; +import java.util.List; +import java.util.Map; + public interface ServerCommands { /** @@ -229,6 +235,8 @@ default void shutdown(SaveMode saveMode) throws JedisException { String lolwut(LolwutParams lolwutParams); + String reset(); + /** * The LATENCY DOCTOR command reports about different latency-related issues and advises about * possible remedies. @@ -244,4 +252,10 @@ default void shutdown(SaveMode saveMode) throws JedisException { * @return the report */ String latencyDoctor(); + + Map latencyLatest(); + + List latencyHistory(LatencyEvent events); + + long latencyReset(LatencyEvent... events); } diff --git a/src/main/java/redis/clients/jedis/commands/StreamBinaryCommands.java b/src/main/java/redis/clients/jedis/commands/StreamBinaryCommands.java index 0b43ebbcc3..01dec14d2d 100644 --- a/src/main/java/redis/clients/jedis/commands/StreamBinaryCommands.java +++ b/src/main/java/redis/clients/jedis/commands/StreamBinaryCommands.java @@ -15,13 +15,13 @@ default byte[] xadd(byte[] key, Map hash, XAddParams params) { long xlen(byte[] key); - List xrange(byte[] key, byte[] start, byte[] end); + List xrange(byte[] key, byte[] start, byte[] end); - List xrange(byte[] key, byte[] start, byte[] end, int count); + List xrange(byte[] key, byte[] start, byte[] end, int count); - List xrevrange(byte[] key, byte[] end, byte[] start); + List xrevrange(byte[] key, byte[] end, byte[] start); - List xrevrange(byte[] key, byte[] end, byte[] start, int count); + List xrevrange(byte[] key, byte[] end, byte[] start, int count); long xack(byte[] key, byte[] group, byte[]... ids); @@ -74,9 +74,9 @@ List xautoclaimJustId(byte[] key, byte[] groupName, byte[] consumerName, List xinfoConsumers(byte[] key, byte[] group); - List xread(XReadParams xReadParams, Map.Entry... streams); + List xread(XReadParams xReadParams, Map.Entry... streams); - List xreadGroup(byte[] groupName, byte[] consumer, XReadGroupParams xReadGroupParams, + List xreadGroup(byte[] groupName, byte[] consumer, XReadGroupParams xReadGroupParams, Map.Entry... streams); } diff --git a/src/main/java/redis/clients/jedis/commands/StreamCommands.java b/src/main/java/redis/clients/jedis/commands/StreamCommands.java index 6f1245b136..9c34cbc6a6 100644 --- a/src/main/java/redis/clients/jedis/commands/StreamCommands.java +++ b/src/main/java/redis/clients/jedis/commands/StreamCommands.java @@ -123,16 +123,6 @@ default StreamEntryID xadd(String key, Map hash, XAddParams para */ long xgroupDelConsumer(String key, String groupName, String consumerName); - /** - * XPENDING key group - */ - StreamPendingSummary xpending(String key, String groupName); - - /** - * XPENDING key group [[IDLE min-idle-time] start end count [consumer]] - */ - List xpending(String key, String groupName, XPendingParams params); - /** * XDEL key ID [ID ...] */ @@ -148,6 +138,16 @@ default StreamEntryID xadd(String key, Map hash, XAddParams para */ long xtrim(String key, XTrimParams params); + /** + * XPENDING key group + */ + StreamPendingSummary xpending(String key, String groupName); + + /** + * XPENDING key group [[IDLE min-idle-time] start end count [consumer]] + */ + List xpending(String key, String groupName, XPendingParams params); + /** * {@code XCLAIM key group consumer min-idle-time ... * [IDLE ] [TIME ] [RETRYCOUNT ] diff --git a/src/main/java/redis/clients/jedis/commands/StreamPipelineBinaryCommands.java b/src/main/java/redis/clients/jedis/commands/StreamPipelineBinaryCommands.java index 8acb88a049..8198443009 100644 --- a/src/main/java/redis/clients/jedis/commands/StreamPipelineBinaryCommands.java +++ b/src/main/java/redis/clients/jedis/commands/StreamPipelineBinaryCommands.java @@ -16,13 +16,13 @@ default Response xadd(byte[] key, Map hash, XAddParams p Response xlen(byte[] key); - Response> xrange(byte[] key, byte[] start, byte[] end); + Response> xrange(byte[] key, byte[] start, byte[] end); - Response> xrange(byte[] key, byte[] start, byte[] end, int count); + Response> xrange(byte[] key, byte[] start, byte[] end, int count); - Response> xrevrange(byte[] key, byte[] end, byte[] start); + Response> xrevrange(byte[] key, byte[] end, byte[] start); - Response> xrevrange(byte[] key, byte[] end, byte[] start, int count); + Response> xrevrange(byte[] key, byte[] end, byte[] start, int count); Response xack(byte[] key, byte[] group, byte[]... ids); @@ -75,9 +75,9 @@ Response> xautoclaimJustId(byte[] key, byte[] groupName, byte[] con Response> xinfoConsumers(byte[] key, byte[] group); - Response> xread(XReadParams xReadParams, Map.Entry... streams); + Response> xread(XReadParams xReadParams, Map.Entry... streams); - Response> xreadGroup(byte[] groupName, byte[] consumer, XReadGroupParams xReadGroupParams, - Map.Entry... streams); + Response> xreadGroup(byte[] groupName, byte[] consumer, + XReadGroupParams xReadGroupParams, Map.Entry... streams); } diff --git a/src/main/java/redis/clients/jedis/exceptions/AbortedTransactionException.java b/src/main/java/redis/clients/jedis/exceptions/AbortedTransactionException.java deleted file mode 100644 index 25f857a6c0..0000000000 --- a/src/main/java/redis/clients/jedis/exceptions/AbortedTransactionException.java +++ /dev/null @@ -1,16 +0,0 @@ -package redis.clients.jedis.exceptions; - -public class AbortedTransactionException extends JedisDataException { - - public AbortedTransactionException(final String message) { - super(message); - } - - public AbortedTransactionException(final Throwable cause) { - super(cause); - } - - public AbortedTransactionException(final String message, final Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/redis/clients/jedis/exceptions/JedisBroadcastException.java b/src/main/java/redis/clients/jedis/exceptions/JedisBroadcastException.java index d0670a2c85..172449c34d 100644 --- a/src/main/java/redis/clients/jedis/exceptions/JedisBroadcastException.java +++ b/src/main/java/redis/clients/jedis/exceptions/JedisBroadcastException.java @@ -1,5 +1,6 @@ package redis.clients.jedis.exceptions; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import redis.clients.jedis.HostAndPort; @@ -8,45 +9,22 @@ * Note: This exception extends {@link JedisDataException} just so existing applications catching * JedisDataException do not get broken. */ +// TODO: extends JedisException public class JedisBroadcastException extends JedisDataException { private static final String BROADCAST_ERROR_MESSAGE = "A failure occurred while broadcasting the command."; - private final Map replies = new HashMap<>(); + private final Map replies = new HashMap<>(); public JedisBroadcastException() { super(BROADCAST_ERROR_MESSAGE); } public void addReply(HostAndPort node, Object reply) { - replies.put(node, new SingleReply(reply)); + replies.put(node, reply); } - public void addError(HostAndPort node, JedisDataException error) { - replies.put(node, new SingleReply(error)); - } - - public static class SingleReply { - - private final Object reply; - private final JedisDataException error; - - public SingleReply(Object reply) { - this.reply = reply; - this.error = null; - } - - public SingleReply(JedisDataException error) { - this.reply = null; - this.error = error; - } - - public Object getReply() { - return reply; - } - - public JedisDataException getError() { - return error; - } + public Map getReplies() { + return Collections.unmodifiableMap(replies); } } diff --git a/src/main/java/redis/clients/jedis/executors/CircuitBreakerCommandExecutor.java b/src/main/java/redis/clients/jedis/executors/CircuitBreakerCommandExecutor.java deleted file mode 100644 index a01a58d98d..0000000000 --- a/src/main/java/redis/clients/jedis/executors/CircuitBreakerCommandExecutor.java +++ /dev/null @@ -1,95 +0,0 @@ -package redis.clients.jedis.executors; - -import io.github.resilience4j.circuitbreaker.CallNotPermittedException; -import io.github.resilience4j.circuitbreaker.CircuitBreaker; -import io.github.resilience4j.decorators.Decorators; -import io.github.resilience4j.decorators.Decorators.DecorateSupplier; -import redis.clients.jedis.*; -import redis.clients.jedis.exceptions.JedisConnectionException; -import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider; -import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider.Cluster; -import redis.clients.jedis.util.IOUtils; - -import java.util.Arrays; -import java.util.List; - - -/** - * @author Allen Terleto (aterleto) - *

- * CommandExecutor with built-in retry, circuit-breaker, and failover to another cluster/database endpoint. - * With this executor users can seamlessly failover to Disaster Recovery (DR), Backup, and Active-Active cluster(s) - * by using simple configuration which is passed through from Resilience4j - https://resilience4j.readme.io/docs - *

- */ -public class CircuitBreakerCommandExecutor implements CommandExecutor { - - private final static List> circuitBreakerFallbackException = - Arrays.asList(CallNotPermittedException.class); - - private final MultiClusterPooledConnectionProvider provider; - - public CircuitBreakerCommandExecutor(MultiClusterPooledConnectionProvider provider) { - this.provider = provider; - } - - @Override - public void close() { - IOUtils.closeQuietly(this.provider); - } - - @Override - public T executeCommand(CommandObject commandObject) { - Cluster cluster = provider.getCluster(); // Pass this by reference for thread safety - - DecorateSupplier supplier = Decorators.ofSupplier(() -> this.handleExecuteCommand(commandObject, cluster)); - - supplier.withRetry(cluster.getRetry()); - supplier.withCircuitBreaker(cluster.getCircuitBreaker()); - supplier.withFallback(circuitBreakerFallbackException, - e -> this.handleClusterFailover(commandObject, cluster.getCircuitBreaker())); - - return supplier.decorate().get(); - } - - /** - * Functional interface wrapped in retry and circuit breaker logic to handle happy path scenarios - */ - private T handleExecuteCommand(CommandObject commandObject, Cluster cluster) { - try (Connection connection = cluster.getConnection()) { - return connection.executeCommand(commandObject); - } - } - - /** - * Functional interface wrapped in retry and circuit breaker logic to handle open circuit breaker failure scenarios - */ - private synchronized T handleClusterFailover(CommandObject commandObject, CircuitBreaker circuitBreaker) { - - // Check state to handle race conditions since incrementActiveMultiClusterIndex() is non-idempotent - if (!CircuitBreaker.State.FORCED_OPEN.equals(circuitBreaker.getState())) { - - // Transitions state machine to a FORCED_OPEN state, stopping state transition, metrics and event publishing. - // To recover/transition from this forced state the user will need to manually failback - circuitBreaker.transitionToForcedOpenState(); - - // Incrementing the activeMultiClusterIndex will allow subsequent calls to the executeCommand() - // to use the next cluster's connection pool - according to the configuration's prioritization/order - int activeMultiClusterIndex = provider.incrementActiveMultiClusterIndex(); - - // Implementation is optionally provided during configuration. Typically, used for activeMultiClusterIndex persistence or custom logging - provider.runClusterFailoverPostProcessor(activeMultiClusterIndex); - } - - // Once the priority list is exhausted only a manual failback can open the circuit breaker so all subsequent operations will fail - else if (provider.isLastClusterCircuitBreakerForcedOpen()) { - throw new JedisConnectionException("Cluster/database endpoint could not failover since the MultiClusterClientConfig was not " + - "provided with an additional cluster/database endpoint according to its prioritized sequence. " + - "If applicable, consider failing back OR restarting with an available cluster/database endpoint"); - } - - // Recursive call to the initiating method so the operation can be retried on the next cluster connection - return executeCommand(commandObject); - } - -} \ No newline at end of file diff --git a/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java b/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java index 48ed4cd6a0..4cc25c42a9 100644 --- a/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java +++ b/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java @@ -43,30 +43,29 @@ public final T broadcastCommand(CommandObject commandObject) { boolean isErrored = false; T reply = null; - JedisBroadcastException holder = new JedisBroadcastException(); + JedisBroadcastException bcastError = new JedisBroadcastException(); for (Map.Entry entry : connectionMap.entrySet()) { HostAndPort node = HostAndPort.from(entry.getKey()); ConnectionPool pool = entry.getValue(); try (Connection connection = pool.getResource()) { - try { - T aReply = execute(connection, commandObject); - holder.addReply(node, aReply); - if (isErrored) { // already errored - } else if (reply == null) { - reply = aReply; // ok - } else if (reply.equals(aReply)) { - // ok - } else { - isErrored = true; - reply = null; - } - } catch (JedisDataException anError) { - holder.addError(node, anError); + T aReply = execute(connection, commandObject); + bcastError.addReply(node, aReply); + if (isErrored) { // already errored + } else if (reply == null) { + reply = aReply; // ok + } else if (reply.equals(aReply)) { + // ok + } else { + isErrored = true; + reply = null; } + } catch (Exception anError) { + bcastError.addReply(node, anError); + isErrored = true; } } if (isErrored) { - throw holder; + throw bcastError; } return reply; } diff --git a/src/main/java/redis/clients/jedis/gears/RedisGearsCommands.java b/src/main/java/redis/clients/jedis/gears/RedisGearsCommands.java new file mode 100644 index 0000000000..f5adb42c9e --- /dev/null +++ b/src/main/java/redis/clients/jedis/gears/RedisGearsCommands.java @@ -0,0 +1,26 @@ +package redis.clients.jedis.gears; + +import redis.clients.jedis.gears.resps.GearsLibraryInfo; + +import java.util.List; + +public interface RedisGearsCommands { + + default String tFunctionLoad(String libraryCode) { + return tFunctionLoad(libraryCode, TFunctionLoadParams.loadParams()); + } + + String tFunctionLoad(String libraryCode, TFunctionLoadParams params); + + default List tFunctionList() { + return tFunctionList(TFunctionListParams.listParams()); + } + + List tFunctionList(TFunctionListParams params); + + String tFunctionDelete(String libraryName); + + Object tFunctionCall(String library, String function, List keys, List args); + + Object tFunctionCallAsync(String library, String function, List keys, List args); +} diff --git a/src/main/java/redis/clients/jedis/gears/RedisGearsProtocol.java b/src/main/java/redis/clients/jedis/gears/RedisGearsProtocol.java new file mode 100644 index 0000000000..fc43f29e66 --- /dev/null +++ b/src/main/java/redis/clients/jedis/gears/RedisGearsProtocol.java @@ -0,0 +1,49 @@ +package redis.clients.jedis.gears; + +import redis.clients.jedis.args.Rawable; +import redis.clients.jedis.commands.ProtocolCommand; +import redis.clients.jedis.util.SafeEncoder; + +public class RedisGearsProtocol { + + public enum GearsCommand implements ProtocolCommand { + + TFUNCTION, + TFCALL, + TFCALLASYNC; + + private final byte[] raw; + + private GearsCommand() { + this.raw = SafeEncoder.encode(name()); + } + + @Override + public byte[] getRaw() { + return raw; + } + } + + public enum GearsKeyword implements Rawable { + + CONFIG, + REPLACE, + LOAD, + DELETE, + LIST, + WITHCODE, + LIBRARY, + VERBOSE; + + private final byte[] raw; + + private GearsKeyword() { + this.raw = SafeEncoder.encode(name()); + } + + @Override + public byte[] getRaw() { + return raw; + } + } +} diff --git a/src/main/java/redis/clients/jedis/gears/TFunctionListParams.java b/src/main/java/redis/clients/jedis/gears/TFunctionListParams.java new file mode 100644 index 0000000000..d3f867e92b --- /dev/null +++ b/src/main/java/redis/clients/jedis/gears/TFunctionListParams.java @@ -0,0 +1,49 @@ +package redis.clients.jedis.gears; + +import redis.clients.jedis.CommandArguments; +import redis.clients.jedis.gears.RedisGearsProtocol.GearsKeyword; +import redis.clients.jedis.params.IParams; + +import java.util.Collections; + +public class TFunctionListParams implements IParams { + private boolean withCode = false; + private int verbose; + private String libraryName; + + public static TFunctionListParams listParams() { + return new TFunctionListParams(); + } + + @Override + public void addParams(CommandArguments args) { + if (withCode) { + args.add(GearsKeyword.WITHCODE); + } + + if (verbose > 0 && verbose < 4) { + args.add(String.join("", Collections.nCopies(verbose, "v"))); + } else if (verbose != 0) { // verbose == 0 is the default, so we don't need to throw an error + throw new IllegalArgumentException("verbose must be between 1 and 3"); + } + + if (libraryName != null) { + args.add(GearsKeyword.LIBRARY).add(libraryName); + } + } + + public TFunctionListParams withCode() { + this.withCode = true; + return this; + } + + public TFunctionListParams verbose(int verbose) { + this.verbose = verbose; + return this; + } + + public TFunctionListParams library(String libraryName) { + this.libraryName = libraryName; + return this; + } +} diff --git a/src/main/java/redis/clients/jedis/gears/TFunctionLoadParams.java b/src/main/java/redis/clients/jedis/gears/TFunctionLoadParams.java new file mode 100644 index 0000000000..d155727ec5 --- /dev/null +++ b/src/main/java/redis/clients/jedis/gears/TFunctionLoadParams.java @@ -0,0 +1,35 @@ +package redis.clients.jedis.gears; + +import redis.clients.jedis.CommandArguments; +import redis.clients.jedis.gears.RedisGearsProtocol.GearsKeyword; +import redis.clients.jedis.params.IParams; + +public class TFunctionLoadParams implements IParams { + private boolean replace = false; + private String config; + + public static TFunctionLoadParams loadParams() { + return new TFunctionLoadParams(); + } + + @Override + public void addParams(CommandArguments args) { + if (replace) { + args.add(GearsKeyword.REPLACE); + } + + if (config != null && !config.isEmpty()) { + args.add(GearsKeyword.CONFIG).add(config); + } + } + + public TFunctionLoadParams replace() { + this.replace = true; + return this; + } + + public TFunctionLoadParams config(String config) { + this.config = config; + return this; + } +} diff --git a/src/main/java/redis/clients/jedis/gears/resps/FunctionInfo.java b/src/main/java/redis/clients/jedis/gears/resps/FunctionInfo.java new file mode 100644 index 0000000000..ccb8785812 --- /dev/null +++ b/src/main/java/redis/clients/jedis/gears/resps/FunctionInfo.java @@ -0,0 +1,97 @@ +package redis.clients.jedis.gears.resps; + +import redis.clients.jedis.Builder; +import redis.clients.jedis.util.KeyValue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static redis.clients.jedis.BuilderFactory.*; + +public class FunctionInfo { + private final String name; + private final String description; + private final boolean isAsync; + + private final List flags; + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public boolean isAsync() { + return isAsync; + } + + public List getFlags() { + return flags; + } + + public FunctionInfo(String name, String description, boolean isAsync, List flags) { + this.name = name; + this.description = description; + this.isAsync = isAsync; + this.flags = flags; + } + + public static final Builder> FUNCTION_INFO_LIST = new Builder>() { + @Override + public List build(Object data) { + List dataAsList = (List) data; + if (!dataAsList.isEmpty()) { + boolean isListOfList = dataAsList.get(0).getClass().isAssignableFrom(ArrayList.class); + + if (isListOfList) { + if (((List>)data).get(0).get(0) instanceof KeyValue) { + List> dataAsKeyValues = (List>)data; + return dataAsKeyValues.stream().map(keyValues -> { + String name = null; + String description = null; + List flags = Collections.emptyList(); + boolean isAsync = false; + for (KeyValue kv : keyValues) { + switch (STRING.build(kv.getKey())) { + case "name": + name = STRING.build(kv.getValue()); + break; + case "description": + description = STRING.build(kv.getValue()); + break; + case "raw-arguments": + flags = STRING_LIST.build(kv.getValue()); + break; + case "is_async": + isAsync = BOOLEAN.build(kv.getValue()); + break; + } + } + return new FunctionInfo(name, description, isAsync, flags); + }).collect(Collectors.toList()); + } else { + return dataAsList.stream().map((pairObject) -> (List) pairObject) + .map((pairList) -> new FunctionInfo( // + STRING.build(pairList.get(7)), // name + STRING.build(pairList.get(1)), // description + BOOLEAN.build(pairList.get(5)), // is_async + STRING_LIST.build(pairList.get(3)) // flags + )).collect(Collectors.toList()); + } + } else { + return dataAsList.stream() // + .map(STRING::build) // + .map((name) -> new FunctionInfo(name, null, false, null)) // + .collect(Collectors.toList()); + } + } else { + return Collections.emptyList(); + } + } + }; +} + diff --git a/src/main/java/redis/clients/jedis/gears/resps/FunctionStreamInfo.java b/src/main/java/redis/clients/jedis/gears/resps/FunctionStreamInfo.java new file mode 100644 index 0000000000..f4b607d6a3 --- /dev/null +++ b/src/main/java/redis/clients/jedis/gears/resps/FunctionStreamInfo.java @@ -0,0 +1,88 @@ +package redis.clients.jedis.gears.resps; + +import redis.clients.jedis.Builder; +import redis.clients.jedis.BuilderFactory; + +import java.util.List; +import java.util.stream.Collectors; + +public class FunctionStreamInfo { + private final String name; + private final String idToReadFrom; + private final String lastError; + private final long lastLag; + private final long lastProcessedTime; + private final long totalLag; + private final long totalProcessedTime; + private final long totalRecordProcessed; + private final List pendingIds; + + public String getName() { + return name; + } + + public String getIdToReadFrom() { + return idToReadFrom; + } + + public String getLastError() { + return lastError; + } + + public long getLastLag() { + return lastLag; + } + + public long getLastProcessedTime() { + return lastProcessedTime; + } + + public long getTotalLag() { + return totalLag; + } + + public long getTotalProcessedTime() { + return totalProcessedTime; + } + + public long getTotalRecordProcessed() { + return totalRecordProcessed; + } + + public List getPendingIds() { + return pendingIds; + } + + public FunctionStreamInfo(String name, String idToReadFrom, String lastError, + long lastProcessedTime, long lastLag, long totalLag, long totalProcessedTime, long totalRecordProcessed, + List pendingIds) { + this.name = name; + this.idToReadFrom = idToReadFrom; + this.lastError = lastError; + this.lastProcessedTime = lastProcessedTime; + this.lastLag = lastLag; + this.totalLag = totalLag; + this.totalProcessedTime = totalProcessedTime; + this.totalRecordProcessed = totalRecordProcessed; + this.pendingIds = pendingIds; + } + + public static final Builder> STREAM_INFO_LIST = new Builder>() { + @Override + public List build(Object data) { + return ((List) data).stream().map((pairObject) -> (List) pairObject) + .map((pairList) -> new FunctionStreamInfo( + BuilderFactory.STRING.build(pairList.get(9)), // name + BuilderFactory.STRING.build(pairList.get(1)), // id_to_read_from + BuilderFactory.STRING.build(pairList.get(3)), // last_error + BuilderFactory.LONG.build(pairList.get(7)), // last_processed_time + BuilderFactory.LONG.build(pairList.get(5)), // last_lag + BuilderFactory.LONG.build(pairList.get(13)), // total_lag + BuilderFactory.LONG.build(pairList.get(15)), // total_processed_time + BuilderFactory.LONG.build(pairList.get(17)), // total_record_processed + BuilderFactory.STRING_LIST.build(pairList.get(11)) // pending_ids + ))// + .collect(Collectors.toList()); + } + }; +} diff --git a/src/main/java/redis/clients/jedis/gears/resps/GearsLibraryInfo.java b/src/main/java/redis/clients/jedis/gears/resps/GearsLibraryInfo.java new file mode 100644 index 0000000000..5ed6515ff6 --- /dev/null +++ b/src/main/java/redis/clients/jedis/gears/resps/GearsLibraryInfo.java @@ -0,0 +1,182 @@ +package redis.clients.jedis.gears.resps; + +import redis.clients.jedis.Builder; +import redis.clients.jedis.util.KeyValue; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static redis.clients.jedis.BuilderFactory.*; +import static redis.clients.jedis.gears.resps.FunctionInfo.FUNCTION_INFO_LIST; +import static redis.clients.jedis.gears.resps.StreamTriggerInfo.STREAM_TRIGGER_INFO_LIST; +import static redis.clients.jedis.gears.resps.TriggerInfo.KEYSPACE_TRIGGER_INFO_LIST; + +public class GearsLibraryInfo { + private final String apiVersion; + private final List clusterFunctions; + private final String code; + private final String configuration; + private final String engine; + private final List functions; + private final List keyspaceTriggers; + private final String name; + private final List pendingAsyncCalls; + private final long pendingJobs; + private final List streamTriggers; + private final String user; + + public GearsLibraryInfo(String apiVersion, List clusterFunctions, String code, String configuration, + String engine, List functions, List keyspaceTriggers, String name, + List pendingAsyncCalls, long pendingJobs, List streamTriggers, String user) { + this.apiVersion = apiVersion; + this.clusterFunctions = clusterFunctions; + this.code = code; + this.configuration = configuration; + this.engine = engine; + this.functions = functions; + this.keyspaceTriggers = keyspaceTriggers; + this.name = name; + this.pendingAsyncCalls = pendingAsyncCalls; + this.pendingJobs = pendingJobs; + this.streamTriggers = streamTriggers; + this.user = user; + } + public String getApiVersion() { + return apiVersion; + } + + public List getClusterFunctions() { + return clusterFunctions; + } + + public String getCode() { + return code; + } + + public String getConfiguration() { + return configuration; + } + + public String getEngine() { + return engine; + } + + public List getFunctions() { + return functions; + } + + public List getKeyspaceTriggers() { + return keyspaceTriggers; + } + + public String getName() { + return name; + } + + public List getPendingAsyncCalls() { + return pendingAsyncCalls; + } + + public long getPendingJobs() { + return pendingJobs; + } + + public List getStreamTriggers() { + return streamTriggers; + } + + public String getUser() { + return user; + } + + public static final Builder GEARS_LIBRARY_INFO = new Builder() { + @Override + public GearsLibraryInfo build(Object data) { + if (data == null) return null; + List list = (List) data; + if (list.isEmpty()) return null; + + String apiVersion = null; + List clusterFunctions = Collections.emptyList(); + String code = null; + String configuration = null; + String engine = null; + List functions = Collections.emptyList(); + List keyspaceTriggers = Collections.emptyList(); + String name = null; + List pendingAsyncCalls = null; + long pendingJobs = 0; + List streamTriggers = Collections.emptyList(); + String user = null; + + if (list.get(0) instanceof KeyValue) { + for (KeyValue kv : (List) list) { + switch (STRING.build(kv.getKey())) { + case "api_version": + apiVersion = STRING.build(kv.getValue()); + break; + case "cluster_functions": + clusterFunctions = STRING_LIST.build(kv.getValue()); + break; + case "configuration": + configuration = STRING.build(kv.getValue()); + break; + case "engine": + engine = STRING.build(kv.getValue()); + break; + case "functions": + functions = FUNCTION_INFO_LIST.build(kv.getValue()); + break; + case "keyspace_triggers": + keyspaceTriggers = KEYSPACE_TRIGGER_INFO_LIST.build(kv.getValue()); + break; + case "name": + name = STRING.build(kv.getValue()); + break; + case "pending_async_calls": + pendingAsyncCalls = STRING_LIST.build(kv.getValue()); + break; + case "pending_jobs": + pendingJobs = LONG.build(kv.getValue()); + break; + case "stream_triggers": + streamTriggers = STREAM_TRIGGER_INFO_LIST.build(kv.getValue()); + break; + case "user": + user = STRING.build(kv.getValue()); + break; + case "code": + code = STRING.build(kv.getValue()); + break; + } + } + } else { + boolean withCode = list.size() > 23; + int offset = withCode ? 2 : 0; + apiVersion = STRING.build(list.get(1)); + clusterFunctions = STRING_LIST.build(list.get(3)); + code = withCode ? STRING.build(list.get(5)) : null; + configuration = STRING.build(list.get(5 + offset)); + engine = STRING.build(list.get(7 + offset)); + functions = FUNCTION_INFO_LIST.build(list.get(9 + offset)); + keyspaceTriggers = KEYSPACE_TRIGGER_INFO_LIST.build(list.get(11 + offset)); + name = STRING.build(list.get(13 + offset)); + pendingAsyncCalls = STRING_LIST.build(list.get(15 + offset)); + pendingJobs = LONG.build(list.get(17 + offset)); + streamTriggers = STREAM_TRIGGER_INFO_LIST.build(list.get(19 + offset)); + user = STRING.build(list.get(21 + offset)); + } + return new GearsLibraryInfo(apiVersion, clusterFunctions, code, configuration, engine, functions, keyspaceTriggers, name, pendingAsyncCalls, pendingJobs, streamTriggers, user); + } + }; + + public static final Builder> GEARS_LIBRARY_INFO_LIST = new Builder>() { + @Override + public List build(Object data) { + List list = (List) data; + return list.stream().map(o -> GearsLibraryInfo.GEARS_LIBRARY_INFO.build(o)).collect(Collectors.toList()); + } + }; + +} \ No newline at end of file diff --git a/src/main/java/redis/clients/jedis/gears/resps/StreamTriggerInfo.java b/src/main/java/redis/clients/jedis/gears/resps/StreamTriggerInfo.java new file mode 100644 index 0000000000..be526e0e71 --- /dev/null +++ b/src/main/java/redis/clients/jedis/gears/resps/StreamTriggerInfo.java @@ -0,0 +1,145 @@ +package redis.clients.jedis.gears.resps; + +import redis.clients.jedis.Builder; +import redis.clients.jedis.util.KeyValue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static redis.clients.jedis.BuilderFactory.*; +import static redis.clients.jedis.gears.resps.FunctionStreamInfo.STREAM_INFO_LIST; + +public class StreamTriggerInfo { + private final String name; + private final String description; + private final String prefix; + private final boolean trim; + private final long window; + private final List streams; + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getPrefix() { + return prefix; + } + public boolean isTrim() { + return trim; + } + + public long getWindow() { + return window; + } + + public List getStreams() { + return streams; + } + + public StreamTriggerInfo(String name, String description, String prefix, + long window, boolean trim, List streams) { + this.name = name; + this.description = description; + this.prefix = prefix; + this.window = window; + this.trim = trim; + this.streams = streams; + } + public StreamTriggerInfo(String name) { + this(name, null, null, 0, false, Collections.emptyList()); + } + + public StreamTriggerInfo(String name, String description, String prefix, + long window, boolean trim) { + this(name, description, prefix, window, trim, Collections.emptyList()); + } + + public static final Builder> STREAM_TRIGGER_INFO_LIST = new Builder>() { + @Override + public List build(Object data) { + List dataAsList = (List) data; + if (!dataAsList.isEmpty()) { + boolean isListOfList = dataAsList.get(0).getClass().isAssignableFrom(ArrayList.class); + if (isListOfList) { + if (((List>)data).get(0).get(0) instanceof KeyValue) { + List> dataAsKeyValues = (List>)data; + return dataAsKeyValues.stream().map(keyValues -> { + String name = null; + String description = null; + String prefix = null; + long window = 0; + boolean trim = false; + List streams = null; + + for (KeyValue kv : keyValues) { + switch (STRING.build(kv.getKey())) { + case "name": + name = STRING.build(kv.getValue()); + break; + case "description": + description = STRING.build(kv.getValue()); + break; + case "prefix": + prefix = STRING.build(kv.getValue()); + break; + case "window": + window = LONG.build(kv.getValue()); + break; + case "trim": + trim = BOOLEAN.build(kv.getValue()); + break; + case "streams": + streams = STREAM_INFO_LIST.build(kv.getValue()); + break; + } + } + return new StreamTriggerInfo(name, description, prefix, window, trim, streams); + }).collect(Collectors.toList()); + } else { + return dataAsList.stream().map((pairObject) -> (List) pairObject).map((pairList) -> { + StreamTriggerInfo result = null; + switch (pairList.size()) { + case 1: + result = new StreamTriggerInfo(STRING.build(pairList.get(0))); + break; + case 10: + result = new StreamTriggerInfo( // + STRING.build(pairList.get(3)), // name + STRING.build(pairList.get(1)), // description + STRING.build(pairList.get(5)), // prefix + LONG.build(pairList.get(9)), // window + BOOLEAN.build(pairList.get(7)) // trim + ); + break; + case 12: + result = new StreamTriggerInfo( // + STRING.build(pairList.get(3)), // name + STRING.build(pairList.get(1)), // description + STRING.build(pairList.get(5)), // prefix + LONG.build(pairList.get(11)), // window + BOOLEAN.build(pairList.get(9)), // trim + STREAM_INFO_LIST.build(pairList.get(7)) // streams + ); + break; + } + return result; + }) // + .collect(Collectors.toList()); + } + } else { + return dataAsList.stream() // + .map(STRING::build).map((name) -> new StreamTriggerInfo(name, null, null, 0, false)) // + .collect(Collectors.toList()); + } + } else { + return Collections.emptyList(); + } + } + }; +} diff --git a/src/main/java/redis/clients/jedis/gears/resps/TriggerInfo.java b/src/main/java/redis/clients/jedis/gears/resps/TriggerInfo.java new file mode 100644 index 0000000000..8a5b470484 --- /dev/null +++ b/src/main/java/redis/clients/jedis/gears/resps/TriggerInfo.java @@ -0,0 +1,162 @@ +package redis.clients.jedis.gears.resps; + +import redis.clients.jedis.Builder; +import redis.clients.jedis.util.KeyValue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static redis.clients.jedis.BuilderFactory.LONG; +import static redis.clients.jedis.BuilderFactory.STRING; + +public class TriggerInfo { + private final String name; + private final String description; + + private final String lastError; + + private final long lastExecutionTime; + + private final long numFailed; + + private final long numFinished; + + private final long numSuccess; + + private final long numTrigger; + + private final long totalExecutionTime; + + + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getLastError() { + return lastError; + } + + public long getLastExecutionTime() { + return lastExecutionTime; + } + + public long getNumFailed() { + return numFailed; + } + + public long getNumFinished() { + return numFinished; + } + + public long getNumSuccess() { + return numSuccess; + } + + public long getNumTrigger() { + return numTrigger; + } + + public long getTotalExecutionTime() { + return totalExecutionTime; + } + + public TriggerInfo(String name, String description, String lastError, long numFinished, long numSuccess, + long numFailed, long numTrigger, long lastExecutionTime, long totalExecutionTime) { + this.name = name; + this.description = description; + this.lastError = lastError; + this.numFinished = numFinished; + this.numSuccess = numSuccess; + this.numFailed = numFailed; + this.numTrigger = numTrigger; + this.lastExecutionTime = lastExecutionTime; + this.totalExecutionTime = totalExecutionTime; + } + + public static final Builder> KEYSPACE_TRIGGER_INFO_LIST = new Builder>() { + @Override + public List build(Object data) { + List dataAsList = (List) data; + if (!dataAsList.isEmpty()) { + boolean isListOfList = dataAsList.get(0).getClass().isAssignableFrom(ArrayList.class); + if (isListOfList) { + if (((List>)data).get(0).get(0) instanceof KeyValue) { + List> dataAsKeyValues = (List>)data; + return dataAsKeyValues.stream().map(keyValues -> { + String name = null; + String description = null; + String lastError = null; + long lastExecutionTime = 0; + long numFailed = 0; + long numFinished = 0; + long numSuccess = 0; + long numTrigger = 0; + long totalExecutionTime = 0; + + for (KeyValue kv : keyValues) { + switch (STRING.build(kv.getKey())) { + case "name": + name = STRING.build(kv.getValue()); + break; + case "description": + description = STRING.build(kv.getValue()); + break; + case "last_error": + lastError = STRING.build(kv.getValue()); + break; + case "last_execution_time": + lastExecutionTime = LONG.build(kv.getValue()); + break; + case "num_failed": + numFailed = LONG.build(kv.getValue()); + break; + case "num_finished": + numFinished = LONG.build(kv.getValue()); + break; + case "num_success": + numSuccess = LONG.build(kv.getValue()); + break; + case "num_trigger": + numTrigger = LONG.build(kv.getValue()); + break; + case "total_execution_time": + totalExecutionTime = LONG.build(kv.getValue()); + break; + } + } + return new TriggerInfo(name, description, lastError, numFinished, numSuccess, numFailed, numTrigger, + lastExecutionTime, totalExecutionTime); + }).collect(Collectors.toList()); + } else { + return dataAsList.stream().map((pairObject) -> (List) pairObject) + .map((pairList) -> new TriggerInfo(STRING.build(pairList.get(7)), // name + STRING.build(pairList.get(1)), // description + STRING.build(pairList.get(3)), // last_error + LONG.build(pairList.get(11)), // num_finished + LONG.build(pairList.get(13)), // num_success + LONG.build(pairList.get(9)), // num_failed + LONG.build(pairList.get(15)), // num_trigger + LONG.build(pairList.get(5)), // last_execution_time + LONG.build(pairList.get(17)) // total_execution_time + ))// + .collect(Collectors.toList()); + } + } else { + return dataAsList.stream() // + .map(STRING::build)// + .map((name) -> new TriggerInfo(name, null, null, 0,0,0,0,0,0)) // + .collect(Collectors.toList()); + } + } else { + return Collections.emptyList(); + } + } + }; +} diff --git a/src/main/java/redis/clients/jedis/mcf/CircuitBreakerCommandExecutor.java b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerCommandExecutor.java new file mode 100644 index 0000000000..38b32bbad0 --- /dev/null +++ b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerCommandExecutor.java @@ -0,0 +1,61 @@ +package redis.clients.jedis.mcf; + +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.decorators.Decorators; +import io.github.resilience4j.decorators.Decorators.DecorateSupplier; + +import redis.clients.jedis.CommandObject; +import redis.clients.jedis.Connection; +import redis.clients.jedis.executors.CommandExecutor; +import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider; +import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider.Cluster; + +/** + * @author Allen Terleto (aterleto) + *

+ * CommandExecutor with built-in retry, circuit-breaker, and failover to another cluster/database endpoint. + * With this executor users can seamlessly failover to Disaster Recovery (DR), Backup, and Active-Active cluster(s) + * by using simple configuration which is passed through from Resilience4j - https://resilience4j.readme.io/docs + *

+ */ +public class CircuitBreakerCommandExecutor extends CircuitBreakerFailoverBase implements CommandExecutor { + + public CircuitBreakerCommandExecutor(MultiClusterPooledConnectionProvider provider) { + super(provider); + } + + @Override + public T executeCommand(CommandObject commandObject) { + Cluster cluster = provider.getCluster(); // Pass this by reference for thread safety + + DecorateSupplier supplier = Decorators.ofSupplier(() -> this.handleExecuteCommand(commandObject, cluster)); + + supplier.withRetry(cluster.getRetry()); + supplier.withCircuitBreaker(cluster.getCircuitBreaker()); + supplier.withFallback(provider.getFallbackExceptionList(), + e -> this.handleClusterFailover(commandObject, cluster.getCircuitBreaker())); + + return supplier.decorate().get(); + } + + /** + * Functional interface wrapped in retry and circuit breaker logic to handle happy path scenarios + */ + private T handleExecuteCommand(CommandObject commandObject, Cluster cluster) { + try (Connection connection = cluster.getConnection()) { + return connection.executeCommand(commandObject); + } + } + + /** + * Functional interface wrapped in retry and circuit breaker logic to handle open circuit breaker failure scenarios + */ + private T handleClusterFailover(CommandObject commandObject, CircuitBreaker circuitBreaker) { + + clusterFailover(circuitBreaker); + + // Recursive call to the initiating method so the operation can be retried on the next cluster connection + return executeCommand(commandObject); + } + +} \ No newline at end of file diff --git a/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverBase.java b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverBase.java new file mode 100644 index 0000000000..b06d7b9604 --- /dev/null +++ b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverBase.java @@ -0,0 +1,58 @@ +package redis.clients.jedis.mcf; + +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import redis.clients.jedis.exceptions.JedisConnectionException; +import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider; +import redis.clients.jedis.util.IOUtils; + +/** + * @author Allen Terleto (aterleto) + *

+ * Base class for CommandExecutor with built-in retry, circuit-breaker, and failover to another cluster/database + * endpoint. With this executor users can seamlessly failover to Disaster Recovery (DR), Backup, and Active-Active + * cluster(s) by using simple configuration which is passed through from + * Resilience4j - https://resilience4j.readme.io/docs + *

+ */ +public class CircuitBreakerFailoverBase implements AutoCloseable { + + protected final MultiClusterPooledConnectionProvider provider; + + public CircuitBreakerFailoverBase(MultiClusterPooledConnectionProvider provider) { + this.provider = provider; + } + + @Override + public void close() { + IOUtils.closeQuietly(this.provider); + } + + /** + * Functional interface wrapped in retry and circuit breaker logic to handle open circuit breaker failure scenarios + */ + protected synchronized void clusterFailover(CircuitBreaker circuitBreaker) { + + // Check state to handle race conditions since incrementActiveMultiClusterIndex() is non-idempotent + if (!CircuitBreaker.State.FORCED_OPEN.equals(circuitBreaker.getState())) { + + // Transitions state machine to a FORCED_OPEN state, stopping state transition, metrics and event publishing. + // To recover/transition from this forced state the user will need to manually failback + circuitBreaker.transitionToForcedOpenState(); + + // Incrementing the activeMultiClusterIndex will allow subsequent calls to the executeCommand() + // to use the next cluster's connection pool - according to the configuration's prioritization/order + int activeMultiClusterIndex = provider.incrementActiveMultiClusterIndex(); + + // Implementation is optionally provided during configuration. Typically, used for activeMultiClusterIndex persistence or custom logging + provider.runClusterFailoverPostProcessor(activeMultiClusterIndex); + } + + // Once the priority list is exhausted only a manual failback can open the circuit breaker so all subsequent operations will fail + else if (provider.isLastClusterCircuitBreakerForcedOpen()) { + throw new JedisConnectionException("Cluster/database endpoint could not failover since the MultiClusterClientConfig was not " + + "provided with an additional cluster/database endpoint according to its prioritized sequence. " + + "If applicable, consider failing back OR restarting with an available cluster/database endpoint"); + } + } + +} \ No newline at end of file diff --git a/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverConnectionProvider.java b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverConnectionProvider.java new file mode 100644 index 0000000000..10a0823973 --- /dev/null +++ b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverConnectionProvider.java @@ -0,0 +1,55 @@ +package redis.clients.jedis.mcf; + +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.decorators.Decorators; +import io.github.resilience4j.decorators.Decorators.DecorateSupplier; + +import redis.clients.jedis.Connection; +import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider; +import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider.Cluster; + +/** + * ConnectionProvider with built-in retry, circuit-breaker, and failover to another cluster/database endpoint. + * With this executor users can seamlessly failover to Disaster Recovery (DR), Backup, and Active-Active cluster(s) + * by using simple configuration which is passed through from Resilience4j - https://resilience4j.readme.io/docs + */ +public class CircuitBreakerFailoverConnectionProvider extends CircuitBreakerFailoverBase { + + public CircuitBreakerFailoverConnectionProvider(MultiClusterPooledConnectionProvider provider) { + super(provider); + } + + public Connection getConnection() { + Cluster cluster = provider.getCluster(); // Pass this by reference for thread safety + + DecorateSupplier supplier = Decorators.ofSupplier(() -> this.handleGetConnection(cluster)); + + supplier.withRetry(cluster.getRetry()); + supplier.withCircuitBreaker(cluster.getCircuitBreaker()); + supplier.withFallback(provider.getFallbackExceptionList(), + e -> this.handleClusterFailover(cluster.getCircuitBreaker())); + + return supplier.decorate().get(); + } + + /** + * Functional interface wrapped in retry and circuit breaker logic to handle happy path scenarios + */ + private Connection handleGetConnection(Cluster cluster) { + Connection connection = cluster.getConnection(); + connection.ping(); + return connection; + } + + /** + * Functional interface wrapped in retry and circuit breaker logic to handle open circuit breaker failure scenarios + */ + private Connection handleClusterFailover(CircuitBreaker circuitBreaker) { + + clusterFailover(circuitBreaker); + + // Recursive call to the initiating method so the operation can be retried on the next cluster connection + return getConnection(); + } + +} \ No newline at end of file diff --git a/src/main/java/redis/clients/jedis/mcf/MultiClusterPipeline.java b/src/main/java/redis/clients/jedis/mcf/MultiClusterPipeline.java new file mode 100644 index 0000000000..00c0ba1d91 --- /dev/null +++ b/src/main/java/redis/clients/jedis/mcf/MultiClusterPipeline.java @@ -0,0 +1,131 @@ +package redis.clients.jedis.mcf; + +import java.io.Closeable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +import redis.clients.jedis.*; +import redis.clients.jedis.graph.ResultSet; +import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider; +import redis.clients.jedis.util.KeyValue; + +/** + * This is high memory dependent solution as all the appending commands will be hold in memory until + * {@link MultiClusterPipeline#sync() SYNC} (or {@link MultiClusterPipeline#close() CLOSE}) gets called. + */ +public class MultiClusterPipeline extends PipelineBase implements Closeable { + + private final CircuitBreakerFailoverConnectionProvider failoverProvider; + private final Queue>> commands = new LinkedList<>(); + + @Deprecated + public MultiClusterPipeline(MultiClusterPooledConnectionProvider pooledProvider) { + super(new CommandObjects()); + + this.failoverProvider = new CircuitBreakerFailoverConnectionProvider(pooledProvider); + + try (Connection connection = failoverProvider.getConnection()) { + RedisProtocol proto = connection.getRedisProtocol(); + if (proto != null) this.commandObjects.setProtocol(proto); + } + } + + public MultiClusterPipeline(MultiClusterPooledConnectionProvider pooledProvider, CommandObjects commandObjects) { + super(commandObjects); + this.failoverProvider = new CircuitBreakerFailoverConnectionProvider(pooledProvider); + } + + @Override + protected final Response appendCommand(CommandObject commandObject) { + CommandArguments args = commandObject.getArguments(); + Response response = new Response<>(commandObject.getBuilder()); + commands.add(KeyValue.of(args, response)); + return response; + } + + @Override + public void close() { + sync(); + // connection prepared and closed (in try-with-resources) in sync() + } + + /** + * Synchronize pipeline by reading all responses. This operation close the pipeline. In order to get return values + * from pipelined commands, capture the different Response<?> of the commands you execute. + */ + @Override + public void sync() { + if (commands.isEmpty()) return; + + try (Connection connection = failoverProvider.getConnection()) { + + commands.forEach((command) -> connection.sendCommand(command.getKey())); + // following connection.getMany(int) flushes anyway, so no flush here. + + List unformatted = connection.getMany(commands.size()); + unformatted.forEach((rawReply) -> commands.poll().getValue().set(rawReply)); + } + } + + public Response waitReplicas(int replicas, long timeout) { + return appendCommand(commandObjects.waitReplicas(replicas, timeout)); + } + + public Response> waitAOF(long numLocal, long numReplicas, long timeout) { + return appendCommand(commandObjects.waitAOF(numLocal, numReplicas, timeout)); + } + + // RedisGraph commands + @Override + public Response graphQuery(String name, String query) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphReadonlyQuery(String name, String query) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphQuery(String name, String query, long timeout) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphReadonlyQuery(String name, String query, long timeout) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphQuery(String name, String query, Map params) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphReadonlyQuery(String name, String query, Map params) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphQuery(String name, String query, Map params, long timeout) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphReadonlyQuery(String name, String query, Map params, long timeout) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphDelete(String name) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response> graphProfile(String graphName, String query) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + // RedisGraph commands +} diff --git a/src/main/java/redis/clients/jedis/mcf/MultiClusterTransaction.java b/src/main/java/redis/clients/jedis/mcf/MultiClusterTransaction.java new file mode 100644 index 0000000000..d759ce1da0 --- /dev/null +++ b/src/main/java/redis/clients/jedis/mcf/MultiClusterTransaction.java @@ -0,0 +1,262 @@ +package redis.clients.jedis.mcf; + +import static redis.clients.jedis.Protocol.Command.DISCARD; +import static redis.clients.jedis.Protocol.Command.EXEC; +import static redis.clients.jedis.Protocol.Command.MULTI; +import static redis.clients.jedis.Protocol.Command.UNWATCH; +import static redis.clients.jedis.Protocol.Command.WATCH; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.atomic.AtomicInteger; + +import redis.clients.jedis.*; +import redis.clients.jedis.exceptions.JedisDataException; +import redis.clients.jedis.graph.ResultSet; +import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider; +import redis.clients.jedis.util.KeyValue; + +/** + * This is high memory dependent solution as all the appending commands will be hold in memory. + */ +public class MultiClusterTransaction extends TransactionBase { + + private static final Builder NO_OP_BUILDER = BuilderFactory.RAW_OBJECT; + + private final CircuitBreakerFailoverConnectionProvider failoverProvider; + private final AtomicInteger extraCommandCount = new AtomicInteger(); + private final Queue>> commands = new LinkedList<>(); + + private boolean inWatch = false; + private boolean inMulti = false; + + /** + * A MULTI command will be added to be sent to server. WATCH/UNWATCH/MULTI commands must not be + * called with this object. + * @param provider + */ + @Deprecated + public MultiClusterTransaction(MultiClusterPooledConnectionProvider provider) { + this(provider, true); + } + + /** + * A user wanting to WATCH/UNWATCH keys followed by a call to MULTI ({@link #multi()}) it should + * be {@code doMulti=false}. + * + * @param provider + * @param doMulti {@code false} should be set to enable manual WATCH, UNWATCH and MULTI + */ + @Deprecated + public MultiClusterTransaction(MultiClusterPooledConnectionProvider provider, boolean doMulti) { + this.failoverProvider = new CircuitBreakerFailoverConnectionProvider(provider); + + try (Connection connection = failoverProvider.getConnection()) { + RedisProtocol proto = connection.getRedisProtocol(); + if (proto != null) this.commandObjects.setProtocol(proto); + } + + if (doMulti) multi(); + } + + /** + * A user wanting to WATCH/UNWATCH keys followed by a call to MULTI ({@link #multi()}) it should + * be {@code doMulti=false}. + * + * @param provider + * @param doMulti {@code false} should be set to enable manual WATCH, UNWATCH and MULTI + * @param commandObjects command objects + */ + public MultiClusterTransaction(MultiClusterPooledConnectionProvider provider, boolean doMulti, CommandObjects commandObjects) { + super(commandObjects); + this.failoverProvider = new CircuitBreakerFailoverConnectionProvider(provider); + + if (doMulti) multi(); + } + + @Override + public final void multi() { + appendCommand(new CommandObject<>(new CommandArguments(MULTI), NO_OP_BUILDER)); + extraCommandCount.incrementAndGet(); + inMulti = true; + } + + /** + * @param keys + * @return {@code null} + */ + @Override + public final String watch(String... keys) { + appendCommand(new CommandObject<>(new CommandArguments(WATCH).addObjects((Object[]) keys), NO_OP_BUILDER)); + extraCommandCount.incrementAndGet(); + inWatch = true; + return null; + } + + /** + * @param keys + * @return {@code null} + */ + @Override + public final String watch(byte[]... keys) { + appendCommand(new CommandObject<>(new CommandArguments(WATCH).addObjects((Object[]) keys), NO_OP_BUILDER)); + extraCommandCount.incrementAndGet(); + inWatch = true; + return null; + } + + /** + * @return {@code null} + */ + @Override + public final String unwatch() { + appendCommand(new CommandObject<>(new CommandArguments(UNWATCH), NO_OP_BUILDER)); + extraCommandCount.incrementAndGet(); + inWatch = false; + return null; + } + + @Override + protected final Response appendCommand(CommandObject commandObject) { + CommandArguments args = commandObject.getArguments(); + Response response = new Response<>(commandObject.getBuilder()); + commands.add(KeyValue.of(args, response)); + return response; + } + + @Override + public void close() { + clear(); + } + + private void clear() { + if (inMulti) { + discard(); + } else if (inWatch) { + unwatch(); + } + } + + @Override + public final List exec() { + if (!inMulti) { + throw new IllegalStateException("EXEC without MULTI"); + } + + try (Connection connection = failoverProvider.getConnection()) { + + commands.forEach((command) -> connection.sendCommand(command.getKey())); + // following connection.getMany(int) flushes anyway, so no flush here. + + // ignore QUEUED (or ERROR) + connection.getMany(commands.size()); + + // remove extra response builders + for (int idx = 0; idx < extraCommandCount.get(); ++idx) { + commands.poll(); + } + + connection.sendCommand(EXEC); + + List unformatted = connection.getObjectMultiBulkReply(); + if (unformatted == null) { + commands.clear(); + return null; + } + + List formatted = new ArrayList<>(unformatted.size() - extraCommandCount.get()); + for (Object rawReply: unformatted) { + try { + Response response = commands.poll().getValue(); + response.set(rawReply); + formatted.add(response.get()); + } catch (JedisDataException e) { + formatted.add(e); + } + } + return formatted; + + } finally { + inMulti = false; + inWatch = false; + } + } + + @Override + public final String discard() { + if (!inMulti) { + throw new IllegalStateException("DISCARD without MULTI"); + } + + try (Connection connection = failoverProvider.getConnection()) { + + commands.forEach((command) -> connection.sendCommand(command.getKey())); + // following connection.getMany(int) flushes anyway, so no flush here. + + // ignore QUEUED (or ERROR) + connection.getMany(commands.size()); + + connection.sendCommand(DISCARD); + + return connection.getStatusCodeReply(); + } finally { + inMulti = false; + inWatch = false; + } + } + + // RedisGraph commands + @Override + public Response graphQuery(String name, String query) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphReadonlyQuery(String name, String query) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphQuery(String name, String query, long timeout) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphReadonlyQuery(String name, String query, long timeout) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphQuery(String name, String query, Map params) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphReadonlyQuery(String name, String query, Map params) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphQuery(String name, String query, Map params, long timeout) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphReadonlyQuery(String name, String query, Map params, long timeout) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response graphDelete(String name) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + + @Override + public Response> graphProfile(String graphName, String query) { + throw new UnsupportedOperationException("Graph commands are not supported."); + } + // RedisGraph commands +} diff --git a/src/main/java/redis/clients/jedis/mcf/package-info.java b/src/main/java/redis/clients/jedis/mcf/package-info.java new file mode 100644 index 0000000000..6b89d9c77b --- /dev/null +++ b/src/main/java/redis/clients/jedis/mcf/package-info.java @@ -0,0 +1,4 @@ +/** + * This package contains the classes that are related to Active-Active cluster(s) and Multi-Cluster failover. + */ +package redis.clients.jedis.mcf; diff --git a/src/main/java/redis/clients/jedis/params/ClientKillParams.java b/src/main/java/redis/clients/jedis/params/ClientKillParams.java index 12c65be882..0082ef3340 100644 --- a/src/main/java/redis/clients/jedis/params/ClientKillParams.java +++ b/src/main/java/redis/clients/jedis/params/ClientKillParams.java @@ -67,6 +67,16 @@ public ClientKillParams laddr(String ip, int port) { return addParam(Keyword.LADDR, ip + ':' + port); } + /** + * Kill clients older than {@code maxAge} seconds. + * + * @param maxAge Clients older than this number of seconds will be killed. + * @return The {@code ClientKillParams} instance, for call chaining. + */ + public ClientKillParams maxAge(long maxAge) { + return addParam(Keyword.MAXAGE, maxAge); + } + @Override public void addParams(CommandArguments args) { params.forEach(kv -> args.add(kv.getKey()).add(kv.getValue())); diff --git a/src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java b/src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java index 4c47f2094b..c21640713d 100644 --- a/src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java +++ b/src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java @@ -1,5 +1,6 @@ package redis.clients.jedis.providers; +import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -17,9 +18,9 @@ import redis.clients.jedis.exceptions.JedisClusterOperationException; import redis.clients.jedis.exceptions.JedisException; -public class ClusterConnectionProvider implements ConnectionProvider { +import static redis.clients.jedis.JedisCluster.INIT_NO_ERROR_PROPERTY; - private static final String INIT_NO_ERROR_PROPERTY = "jedis.cluster.initNoError"; +public class ClusterConnectionProvider implements ConnectionProvider { protected final JedisClusterInfoCache cache; @@ -34,6 +35,12 @@ public ClusterConnectionProvider(Set clusterNodes, JedisClientConfi initializeSlotsCache(clusterNodes, clientConfig); } + public ClusterConnectionProvider(Set clusterNodes, JedisClientConfig clientConfig, + GenericObjectPoolConfig poolConfig, Duration topologyRefreshPeriod) { + this.cache = new JedisClusterInfoCache(clientConfig, poolConfig, clusterNodes, topologyRefreshPeriod); + initializeSlotsCache(clusterNodes, clientConfig); + } + private void initializeSlotsCache(Set startNodes, JedisClientConfig clientConfig) { if (startNodes.isEmpty()) { throw new JedisClusterOperationException("No nodes to initialize cluster slots cache."); @@ -66,7 +73,7 @@ private void initializeSlotsCache(Set startNodes, JedisClientConfig @Override public void close() { - cache.reset(); + cache.close(); } public void renewSlotCache() { diff --git a/src/main/java/redis/clients/jedis/providers/MultiClusterPooledConnectionProvider.java b/src/main/java/redis/clients/jedis/providers/MultiClusterPooledConnectionProvider.java index abe5515b97..e6013a2c58 100644 --- a/src/main/java/redis/clients/jedis/providers/MultiClusterPooledConnectionProvider.java +++ b/src/main/java/redis/clients/jedis/providers/MultiClusterPooledConnectionProvider.java @@ -8,18 +8,21 @@ import io.github.resilience4j.retry.Retry; import io.github.resilience4j.retry.RetryConfig; import io.github.resilience4j.retry.RetryRegistry; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import redis.clients.jedis.*; import redis.clients.jedis.MultiClusterClientConfig.ClusterConfig; import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisValidationException; import redis.clients.jedis.util.Pool; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - /** * @author Allen Terleto (aterleto) @@ -31,6 +34,7 @@ * Support for manual failback is provided by way of {@link #setActiveMultiClusterIndex(int)} *

*/ +// TODO: move? public class MultiClusterPooledConnectionProvider implements ConnectionProvider { private final Logger log = LoggerFactory.getLogger(getClass()); @@ -62,6 +66,7 @@ public class MultiClusterPooledConnectionProvider implements ConnectionProvider */ private Consumer clusterFailoverPostProcessor; + private List> fallbackExceptionList; public MultiClusterPooledConnectionProvider(MultiClusterClientConfig multiClusterClientConfig) { @@ -78,7 +83,7 @@ public MultiClusterPooledConnectionProvider(MultiClusterClientConfig multiCluste retryConfigBuilder.retryExceptions(multiClusterClientConfig.getRetryIncludedExceptionList().stream().toArray(Class[]::new)); List retryIgnoreExceptionList = multiClusterClientConfig.getRetryIgnoreExceptionList(); - if (retryIgnoreExceptionList != null && !retryIgnoreExceptionList.isEmpty()) + if (retryIgnoreExceptionList != null) retryConfigBuilder.ignoreExceptions(retryIgnoreExceptionList.stream().toArray(Class[]::new)); RetryConfig retryConfig = retryConfigBuilder.build(); @@ -96,7 +101,7 @@ public MultiClusterPooledConnectionProvider(MultiClusterClientConfig multiCluste circuitBreakerConfigBuilder.automaticTransitionFromOpenToHalfOpenEnabled(false); // State transitions are forced. No half open states are used List circuitBreakerIgnoreExceptionList = multiClusterClientConfig.getCircuitBreakerIgnoreExceptionList(); - if (circuitBreakerIgnoreExceptionList != null && !circuitBreakerIgnoreExceptionList.isEmpty()) + if (circuitBreakerIgnoreExceptionList != null) circuitBreakerConfigBuilder.ignoreExceptions(circuitBreakerIgnoreExceptionList.stream().toArray(Class[]::new)); CircuitBreakerConfig circuitBreakerConfig = circuitBreakerConfigBuilder.build(); @@ -123,10 +128,14 @@ public MultiClusterPooledConnectionProvider(MultiClusterClientConfig multiCluste circuitBreakerEventPublisher.onSlowCallRateExceeded(event -> log.error(String.valueOf(event))); circuitBreakerEventPublisher.onStateTransition(event -> log.warn(String.valueOf(event))); - multiClusterMap.put(config.getPriority(), new Cluster(new ConnectionPool(config.getHostAndPort(), - config.getJedisClientConfig()), - retry, circuitBreaker)); + multiClusterMap.put(config.getPriority(), + new Cluster(new ConnectionPool(config.getHostAndPort(), + config.getJedisClientConfig()), retry, circuitBreaker)); } + + /// --- /// + + this.fallbackExceptionList = multiClusterClientConfig.getFallbackExceptionList(); } /** @@ -289,6 +298,10 @@ public void setClusterFailoverPostProcessor(Consumer clusterFailoverPost this.clusterFailoverPostProcessor = clusterFailoverPostProcessor; } + public List> getFallbackExceptionList() { + return fallbackExceptionList; + } + public static class Cluster { private final ConnectionPool connectionPool; diff --git a/src/main/java/redis/clients/jedis/resps/ClusterShardInfo.java b/src/main/java/redis/clients/jedis/resps/ClusterShardInfo.java new file mode 100644 index 0000000000..8e7394bccc --- /dev/null +++ b/src/main/java/redis/clients/jedis/resps/ClusterShardInfo.java @@ -0,0 +1,44 @@ +package redis.clients.jedis.resps; + +import java.util.List; +import java.util.Map; + +/** + * This class holds information about a shard of the cluster with command {@code CLUSTER SHARDS}. + * They can be accessed via getters. There is also {@link ClusterShardInfo#getClusterShardInfo()} + * method that returns a generic {@link Map} in case more info are returned from the server. + */ +public class ClusterShardInfo { + + public static final String SLOTS = "slots"; + public static final String NODES = "nodes"; + + private final List> slots; + private final List nodes; + + private final Map clusterShardInfo; + + /** + * @param map contains key-value pairs with cluster shard info + */ + @SuppressWarnings("unchecked") + public ClusterShardInfo(Map map) { + slots = (List>) map.get(SLOTS); + nodes = (List) map.get(NODES); + + clusterShardInfo = map; + } + + public List> getSlots() { + return slots; + } + + public List getNodes() { + return nodes; + } + + public Map getClusterShardInfo() { + return clusterShardInfo; + } + +} diff --git a/src/main/java/redis/clients/jedis/resps/ClusterShardNodeInfo.java b/src/main/java/redis/clients/jedis/resps/ClusterShardNodeInfo.java new file mode 100644 index 0000000000..6e245de4d2 --- /dev/null +++ b/src/main/java/redis/clients/jedis/resps/ClusterShardNodeInfo.java @@ -0,0 +1,94 @@ +package redis.clients.jedis.resps; + +import java.util.Map; + +/** + * This class holds information about a node of the cluster with command {@code CLUSTER SHARDS}. + * They can be accessed via getters. There is also {@link ClusterShardNodeInfo#getClusterShardNodeInfo()} + * method that returns a generic {@link Map} in case more info are returned from the server. + */ +public class ClusterShardNodeInfo { + + public static final String ID = "id"; + public static final String ENDPOINT = "endpoint"; + public static final String IP = "ip"; + public static final String HOSTNAME = "hostname"; + public static final String PORT = "port"; + public static final String TLS_PORT = "tls-port"; + public static final String ROLE = "role"; + public static final String REPLICATION_OFFSET = "replication-offset"; + public static final String HEALTH = "health"; + + private final String id; + private final String endpoint; + private final String ip; + private final String hostname; + private final Long port; + private final Long tlsPort; + private final String role; + private final Long replicationOffset; + private final String health; + + private final Map clusterShardNodeInfo; + + /** + * @param map contains key-value pairs with node info + */ + public ClusterShardNodeInfo(Map map) { + id = (String) map.get(ID); + endpoint = (String) map.get(ENDPOINT); + ip = (String) map.get(IP); + hostname = (String) map.get(HOSTNAME); + port = (Long) map.get(PORT); + tlsPort = (Long) map.get(TLS_PORT); + role = (String) map.get(ROLE); + replicationOffset = (Long) map.get(REPLICATION_OFFSET); + health = (String) map.get(HEALTH); + + clusterShardNodeInfo = map; + } + + public String getId() { + return id; + } + + public String getEndpoint() { + return endpoint; + } + + public String getIp() { + return ip; + } + + public String getHostname() { + return hostname; + } + + public Long getPort() { + return port; + } + + public Long getTlsPort() { + return tlsPort; + } + + public String getRole() { + return role; + } + + public Long getReplicationOffset() { + return replicationOffset; + } + + public String getHealth() { + return health; + } + + public Map getClusterShardNodeInfo() { + return clusterShardNodeInfo; + } + + public boolean isSsl() { + return tlsPort != null; + } +} diff --git a/src/main/java/redis/clients/jedis/resps/GeoRadiusResponse.java b/src/main/java/redis/clients/jedis/resps/GeoRadiusResponse.java index 03a51b2525..d4442bd725 100644 --- a/src/main/java/redis/clients/jedis/resps/GeoRadiusResponse.java +++ b/src/main/java/redis/clients/jedis/resps/GeoRadiusResponse.java @@ -4,8 +4,10 @@ import redis.clients.jedis.util.SafeEncoder; import java.util.Arrays; +import java.util.Objects; public class GeoRadiusResponse { + private byte[] member; private double distance; private GeoCoordinate coordinate; @@ -23,6 +25,10 @@ public void setCoordinate(GeoCoordinate coordinate) { this.coordinate = coordinate; } + public void setRawScore(long rawScore) { + this.rawScore = rawScore; + } + public byte[] getMember() { return member; } @@ -31,22 +37,30 @@ public String getMemberByString() { return SafeEncoder.encode(member); } + /** + * @return The distance of the returned item from the specified center. The distance is returned + * in the same unit as the unit specified as the radius argument of the command. + */ public double getDistance() { return distance; } + /** + * @return The longitude,latitude coordinates of the matching item. + */ public GeoCoordinate getCoordinate() { return coordinate; } + /** + * @return The raw geohash-encoded sorted set score of the item, in the form of a 52 bit unsigned + * integer. This is only useful for low level hacks or debugging and is otherwise of little + * interest for the general user. + */ public long getRawScore() { return rawScore; } - public void setRawScore(long rawScore) { - this.rawScore = rawScore; - } - @Override public boolean equals(Object obj) { if (obj == this) { @@ -62,4 +76,14 @@ public boolean equals(Object obj) { && rawScore == response.getRawScore() && coordinate.equals(response.coordinate) && Arrays.equals(member, response.getMember()); } + + @Override + public int hashCode() { + int hash = 7; + hash = 67 * hash + Arrays.hashCode(this.member); + hash = 67 * hash + (int) (Double.doubleToLongBits(this.distance) ^ (Double.doubleToLongBits(this.distance) >>> 32)); + hash = 67 * hash + Objects.hashCode(this.coordinate); + hash = 67 * hash + (int) (this.rawScore ^ (this.rawScore >>> 32)); + return hash; + } } diff --git a/src/main/java/redis/clients/jedis/resps/LatencyHistoryInfo.java b/src/main/java/redis/clients/jedis/resps/LatencyHistoryInfo.java new file mode 100644 index 0000000000..68867e74e6 --- /dev/null +++ b/src/main/java/redis/clients/jedis/resps/LatencyHistoryInfo.java @@ -0,0 +1,38 @@ +package redis.clients.jedis.resps; + +import redis.clients.jedis.Builder; + +import java.util.List; + +import static redis.clients.jedis.BuilderFactory.LONG; + +public class LatencyHistoryInfo { + + private final long timestamp; + private final long latency; + + public LatencyHistoryInfo(long timestamp, long latency) { + this.timestamp = timestamp; + this.latency = latency; + } + + public long getTimestamp() { + return timestamp; + } + + public long getLatency() { + return latency; + } + + public static final Builder LATENCY_HISTORY_BUILDER = new Builder() { + @Override + public LatencyHistoryInfo build(Object data) { + List commandData = (List) data; + + long timestamp = LONG.build(commandData.get(0)); + long latency = LONG.build(commandData.get(1)); + + return new LatencyHistoryInfo(timestamp, latency); + } + }; +} diff --git a/src/main/java/redis/clients/jedis/resps/LatencyLatestInfo.java b/src/main/java/redis/clients/jedis/resps/LatencyLatestInfo.java new file mode 100644 index 0000000000..b441ea9d75 --- /dev/null +++ b/src/main/java/redis/clients/jedis/resps/LatencyLatestInfo.java @@ -0,0 +1,53 @@ +package redis.clients.jedis.resps; + +import redis.clients.jedis.Builder; + +import java.util.List; + +import static redis.clients.jedis.BuilderFactory.LONG; +import static redis.clients.jedis.BuilderFactory.STRING; + +public class LatencyLatestInfo { + + private final String command; + private final long timestamp; + private final long lastEventLatency; + private final long maxEventLatency; + + public LatencyLatestInfo(String command, long timestamp, long lastEventLatency, long maxEventLatency) { + this.command = command; + this.timestamp = timestamp; + this.lastEventLatency = lastEventLatency; + this.maxEventLatency = maxEventLatency; + } + + public String getCommand() { + return command; + } + + public long getTimestamp() { + return timestamp; + } + + public long getLastEventLatency() { + return lastEventLatency; + } + + public long getMaxEventLatency() { + return maxEventLatency; + } + + public static final Builder LATENCY_LATEST_BUILDER = new Builder() { + @Override + public LatencyLatestInfo build(Object data) { + List commandData = (List) data; + + String command = STRING.build(commandData.get(0)); + long timestamp = LONG.build(commandData.get(1)); + long lastEventLatency = LONG.build(commandData.get(2)); + long maxEventLatency = LONG.build(commandData.get(3)); + + return new LatencyLatestInfo(command, timestamp, lastEventLatency, maxEventLatency); + } + }; +} diff --git a/src/main/java/redis/clients/jedis/resps/LibraryInfo.java b/src/main/java/redis/clients/jedis/resps/LibraryInfo.java index 6471ac9ba7..41cbd49dd3 100644 --- a/src/main/java/redis/clients/jedis/resps/LibraryInfo.java +++ b/src/main/java/redis/clients/jedis/resps/LibraryInfo.java @@ -47,7 +47,7 @@ public String getLibraryCode() { return libraryCode; } - public static final Builder LIBRARY_BUILDER = new Builder() { + public static final Builder LIBRARY_INFO = new Builder() { @Override public LibraryInfo build(Object data) { if (data == null) return null; @@ -88,4 +88,18 @@ public LibraryInfo build(Object data) { } }; + /** + * @deprecated Use {@link LibraryInfo#LIBRARY_INFO}. + */ + @Deprecated + public static final Builder LIBRARY_BUILDER = LIBRARY_INFO; + + public static final Builder> LIBRARY_INFO_LIST = new Builder>() { + @Override + public List build(Object data) { + List list = (List) data; + return list.stream().map(o -> LibraryInfo.LIBRARY_INFO.build(o)).collect(Collectors.toList()); + } + }; + } diff --git a/src/main/java/redis/clients/jedis/search/FieldName.java b/src/main/java/redis/clients/jedis/search/FieldName.java index 452b0b8d61..9a0a9329db 100644 --- a/src/main/java/redis/clients/jedis/search/FieldName.java +++ b/src/main/java/redis/clients/jedis/search/FieldName.java @@ -30,6 +30,14 @@ public FieldName as(String attribute) { return this; } + public final String getName() { + return name; + } + + public final String getAttribute() { + return attribute; + } + public int addCommandArguments(List args) { args.add(name); if (attribute == null) { diff --git a/src/main/java/redis/clients/jedis/search/RediSearchCommands.java b/src/main/java/redis/clients/jedis/search/RediSearchCommands.java index 1e09266ad7..f361689aea 100644 --- a/src/main/java/redis/clients/jedis/search/RediSearchCommands.java +++ b/src/main/java/redis/clients/jedis/search/RediSearchCommands.java @@ -40,6 +40,16 @@ default String ftAlter(String indexName, SchemaField... schemaFields) { String ftAlter(String indexName, Iterable schemaFields); + String ftAliasAdd(String aliasName, String indexName); + + String ftAliasUpdate(String aliasName, String indexName); + + String ftAliasDel(String aliasName); + + String ftDropIndex(String indexName); + + String ftDropIndexDD(String indexName); + default SearchResult ftSearch(String indexName) { return ftSearch(indexName, "*"); } @@ -72,10 +82,6 @@ Map.Entry> ftProfileSearch(String indexName, Map.Entry> ftProfileSearch(String indexName, FTProfileParams profileParams, String query, FTSearchParams searchParams); - String ftDropIndex(String indexName); - - String ftDropIndexDD(String indexName); - String ftSynUpdate(String indexName, String synonymGroupId, String... terms); Map> ftSynDump(String indexName); @@ -101,12 +107,6 @@ Map> ftSpellCheck(String index, String query, Set ftTagVals(String indexName, String fieldName); - String ftAliasAdd(String aliasName, String indexName); - - String ftAliasUpdate(String aliasName, String indexName); - - String ftAliasDel(String aliasName); - Map ftConfigGet(String option); Map ftConfigGet(String indexName, String option); diff --git a/src/main/java/redis/clients/jedis/search/RediSearchPipelineCommands.java b/src/main/java/redis/clients/jedis/search/RediSearchPipelineCommands.java index ed633ea35a..c5765a6f31 100644 --- a/src/main/java/redis/clients/jedis/search/RediSearchPipelineCommands.java +++ b/src/main/java/redis/clients/jedis/search/RediSearchPipelineCommands.java @@ -41,6 +41,16 @@ default Response ftAlter(String indexName, SchemaField... schemaFields) Response ftAlter(String indexName, Iterable schemaFields); + Response ftAliasAdd(String aliasName, String indexName); + + Response ftAliasUpdate(String aliasName, String indexName); + + Response ftAliasDel(String aliasName); + + Response ftDropIndex(String indexName); + + Response ftDropIndexDD(String indexName); + default Response ftSearch(String indexName) { return ftSearch(indexName, "*"); } diff --git a/src/main/java/redis/clients/jedis/search/RediSearchUtil.java b/src/main/java/redis/clients/jedis/search/RediSearchUtil.java index a6a82486b7..14cb963bde 100644 --- a/src/main/java/redis/clients/jedis/search/RediSearchUtil.java +++ b/src/main/java/redis/clients/jedis/search/RediSearchUtil.java @@ -3,8 +3,11 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import redis.clients.jedis.util.SafeEncoder; @@ -18,6 +21,18 @@ public class RediSearchUtil { * @return map with string value */ public static Map toStringMap(Map input) { + return toStringMap(input, false); + } + + /** + * Jedis' {@code hset} methods do not support {@link Object}s as values. This method eases process + * of converting a {@link Map} with Objects as values so that the returning Map can be set to a + * {@code hset} method. + * @param input map with object value + * @param stringEscape whether to escape the String objects + * @return map with string value + */ + public static Map toStringMap(Map input, boolean stringEscape) { Map output = new HashMap<>(input.size()); for (Map.Entry entry : input.entrySet()) { String key = entry.getKey(); @@ -32,9 +47,9 @@ public static Map toStringMap(Map input) { redis.clients.jedis.GeoCoordinate geo = (redis.clients.jedis.GeoCoordinate) obj; str = geo.getLongitude() + "," + geo.getLatitude(); } else if (obj instanceof String) { - str = (String) obj; + str = stringEscape ? escape((String) obj) : (String) obj; } else { - str = obj.toString(); + str = String.valueOf(obj); } output.put(key, str); } @@ -48,12 +63,53 @@ public static Map toStringMap(Map input) { * @param input float array * @return byte array */ - public static byte[] ToByteArray(float[] input) { + public static byte[] toByteArray(float[] input) { byte[] bytes = new byte[Float.BYTES * input.length]; ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer().put(input); return bytes; } + /** + * @deprecated Use {@link RediSearchUtil#toByteArray(float[])}. + */ + @Deprecated + public static byte[] ToByteArray(float[] input) { + return toByteArray(input); + } + + private static final Set ESCAPE_CHARS = new HashSet<>(Arrays.asList(// + ',', '.', '<', '>', '{', '}', '[', // + ']', '"', '\'', ':', ';', '!', '@', // + '#', '$', '%', '^', '&', '*', '(', // + ')', '-', '+', '=', '~', '|' // + )); + + public static String escape(String text) { + return escape(text, false); + } + + public static String escapeQuery(String query) { + return escape(query, true); + } + + public static String escape(String text, boolean querying) { + char[] chars = text.toCharArray(); + + StringBuilder sb = new StringBuilder(); + for (char ch : chars) { + if (ESCAPE_CHARS.contains(ch) + || (querying && ch == ' ')) { + sb.append("\\"); + } + sb.append(ch); + } + return sb.toString(); + } + + public static String unescape(String text) { + return text.replace("\\", ""); + } + private RediSearchUtil() { throw new InstantiationError("Must not instantiate this class"); } diff --git a/src/main/java/redis/clients/jedis/search/SearchProtocol.java b/src/main/java/redis/clients/jedis/search/SearchProtocol.java index 36780b569b..7f2ad482fb 100644 --- a/src/main/java/redis/clients/jedis/search/SearchProtocol.java +++ b/src/main/java/redis/clients/jedis/search/SearchProtocol.java @@ -49,13 +49,13 @@ public byte[] getRaw() { public enum SearchKeyword implements Rawable { - SCHEMA, TEXT, TAG, NUMERIC, GEO, VECTOR, VERBATIM, NOCONTENT, NOSTOPWORDS, WITHSCORES, LANGUAGE, - INFIELDS, SORTBY, ASC, DESC, LIMIT, HIGHLIGHT, FIELDS, TAGS, SUMMARIZE, FRAGS, LEN, SEPARATOR, - INKEYS, RETURN, FILTER, GEOFILTER, ADD, INCR, MAX, FUZZY, READ, DEL, DD, TEMPORARY, STOPWORDS, - NOFREQS, NOFIELDS, NOOFFSETS, NOHL, SET, GET, ON, SORTABLE, UNF, PREFIX, LANGUAGE_FIELD, SCORE, - SCORE_FIELD, SCORER, PARAMS, AS, DIALECT, SLOP, TIMEOUT, INORDER, EXPANDER, MAXTEXTFIELDS, - SKIPINITIALSCAN, WITHSUFFIXTRIE, NOSTEM, NOINDEX, PHONETIC, WEIGHT, CASESENSITIVE, - LOAD, APPLY, GROUPBY, MAXIDLE, WITHCURSOR, DISTANCE, TERMS, INCLUDE, EXCLUDE, + SCHEMA, TEXT, TAG, NUMERIC, GEO, GEOSHAPE, VECTOR, VERBATIM, NOCONTENT, NOSTOPWORDS, WITHSCORES, + LANGUAGE, INFIELDS, SORTBY, ASC, DESC, LIMIT, HIGHLIGHT, FIELDS, TAGS, SUMMARIZE, FRAGS, LEN, + SEPARATOR, INKEYS, RETURN, FILTER, GEOFILTER, ADD, INCR, MAX, FUZZY, READ, DEL, DD, TEMPORARY, + STOPWORDS, NOFREQS, NOFIELDS, NOOFFSETS, NOHL, SET, GET, ON, SORTABLE, UNF, PREFIX, + LANGUAGE_FIELD, SCORE, SCORE_FIELD, SCORER, PARAMS, AS, DIALECT, SLOP, TIMEOUT, INORDER, + EXPANDER, MAXTEXTFIELDS, SKIPINITIALSCAN, WITHSUFFIXTRIE, NOSTEM, NOINDEX, PHONETIC, WEIGHT, + CASESENSITIVE, LOAD, APPLY, GROUPBY, MAXIDLE, WITHCURSOR, DISTANCE, TERMS, INCLUDE, EXCLUDE, SEARCH, AGGREGATE, QUERY, LIMITED, COUNT, REDUCE; private final byte[] raw; diff --git a/src/main/java/redis/clients/jedis/search/aggr/Reducer.java b/src/main/java/redis/clients/jedis/search/aggr/Reducer.java index 21f7060ee7..9cbfb5a00c 100644 --- a/src/main/java/redis/clients/jedis/search/aggr/Reducer.java +++ b/src/main/java/redis/clients/jedis/search/aggr/Reducer.java @@ -29,6 +29,18 @@ public final Reducer as(String alias) { return this; } + public final String getName() { + return name; + } + + public final String getField() { + return field; + } + + public final String getAlias() { + return alias; + } + protected abstract List getOwnArgs(); public final void addArgs(List args) { diff --git a/src/main/java/redis/clients/jedis/search/schemafields/GeoShapeField.java b/src/main/java/redis/clients/jedis/search/schemafields/GeoShapeField.java new file mode 100644 index 0000000000..dd3b45e59e --- /dev/null +++ b/src/main/java/redis/clients/jedis/search/schemafields/GeoShapeField.java @@ -0,0 +1,49 @@ +package redis.clients.jedis.search.schemafields; + +import static redis.clients.jedis.search.SearchProtocol.SearchKeyword.GEOSHAPE; + +import redis.clients.jedis.CommandArguments; +import redis.clients.jedis.search.FieldName; + +public class GeoShapeField extends SchemaField { + + public enum CoordinateSystem { + + /** + * For cartesian (X,Y). + */ + FLAT, + + /** + * For geographic (lon, lat). + */ + SPHERICAL + } + + private final CoordinateSystem system; + + public GeoShapeField(String fieldName, CoordinateSystem system) { + super(fieldName); + this.system = system; + } + + public GeoShapeField(FieldName fieldName, CoordinateSystem system) { + super(fieldName); + this.system = system; + } + + public static GeoShapeField of(String fieldName, CoordinateSystem system) { + return new GeoShapeField(fieldName, system); + } + + @Override + public GeoShapeField as(String attribute) { + super.as(attribute); + return this; + } + + @Override + public void addParams(CommandArguments args) { + args.addParams(fieldName).add(GEOSHAPE).add(system); + } +} diff --git a/src/main/java/redis/clients/jedis/search/schemafields/SchemaField.java b/src/main/java/redis/clients/jedis/search/schemafields/SchemaField.java index 473baea472..8678780da2 100644 --- a/src/main/java/redis/clients/jedis/search/schemafields/SchemaField.java +++ b/src/main/java/redis/clients/jedis/search/schemafields/SchemaField.java @@ -19,4 +19,12 @@ public SchemaField as(String attribute) { fieldName.as(attribute); return this; } + + public final FieldName getFieldName() { + return fieldName; + } + + public final String getName() { + return fieldName.getName(); + } } diff --git a/src/main/java/redis/clients/jedis/search/schemafields/TagField.java b/src/main/java/redis/clients/jedis/search/schemafields/TagField.java index 044f9d75f6..407c4dbddc 100644 --- a/src/main/java/redis/clients/jedis/search/schemafields/TagField.java +++ b/src/main/java/redis/clients/jedis/search/schemafields/TagField.java @@ -106,6 +106,14 @@ public void addParams(CommandArguments args) { args.add(SEPARATOR).add(separator); } + if (caseSensitive) { + args.add(CASESENSITIVE); + } + + if (withSuffixTrie) { + args.add(WITHSUFFIXTRIE); + } + if (sortableUNF) { args.add(SORTABLE).add(UNF); } else if (sortable) { @@ -115,13 +123,5 @@ public void addParams(CommandArguments args) { if (noIndex) { args.add(NOINDEX); } - - if (caseSensitive) { - args.add(CASESENSITIVE); - } - - if (withSuffixTrie) { - args.add(WITHSUFFIXTRIE); - } } } diff --git a/src/main/java/redis/clients/jedis/search/schemafields/TextField.java b/src/main/java/redis/clients/jedis/search/schemafields/TextField.java index f7967383c7..573cae90a3 100644 --- a/src/main/java/redis/clients/jedis/search/schemafields/TextField.java +++ b/src/main/java/redis/clients/jedis/search/schemafields/TextField.java @@ -107,29 +107,30 @@ public void addParams(CommandArguments args) { args.addParams(fieldName); args.add(TEXT); - if (sortableUNF) { - args.add(SORTABLE).add(UNF); - } else if (sortable) { - args.add(SORTABLE); + if (weight != null) { + args.add(WEIGHT).add(weight); } if (noStem) { args.add(NOSTEM); } - if (noIndex) { - args.add(NOINDEX); - } if (phoneticMatcher != null) { args.add(PHONETIC).add(phoneticMatcher); } - if (weight != null) { - args.add(WEIGHT).add(weight); - } - if (withSuffixTrie) { args.add(WITHSUFFIXTRIE); } + + if (sortableUNF) { + args.add(SORTABLE).add(UNF); + } else if (sortable) { + args.add(SORTABLE); + } + + if (noIndex) { + args.add(NOINDEX); + } } } diff --git a/src/main/java/redis/clients/jedis/util/JedisMetaInfo.java b/src/main/java/redis/clients/jedis/util/JedisMetaInfo.java deleted file mode 100644 index c8c6566c4a..0000000000 --- a/src/main/java/redis/clients/jedis/util/JedisMetaInfo.java +++ /dev/null @@ -1,46 +0,0 @@ -package redis.clients.jedis.util; - -import java.io.InputStream; -import java.util.Properties; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Jedis Meta info load version groupId - */ -public class JedisMetaInfo { - private static final Logger log = LoggerFactory.getLogger(JedisMetaInfo.class); - - private static String groupId; - private static String artifactId; - private static String version; - - static { - Properties p = new Properties(); - try { - InputStream in = JedisMetaInfo.class.getClassLoader().getResourceAsStream("pom.properties"); - p.load(in); - - groupId = p.getProperty("groupId", null); - artifactId = p.getProperty("artifactId", null); - version = p.getProperty("version", null); - - in.close(); - } catch (Exception e) { - log.error("Load Jedis meta info from pom.properties failed", e); - } - } - - public static String getGroupId() { - return groupId; - } - - public static String getArtifactId() { - return artifactId; - } - - public static String getVersion() { - return version; - } -} diff --git a/src/main/resources/pom.properties b/src/main/resources/redis/clients/jedis/pom.properties similarity index 100% rename from src/main/resources/pom.properties rename to src/main/resources/redis/clients/jedis/pom.properties diff --git a/src/test/java/redis/clients/jedis/JedisClusterTest.java b/src/test/java/redis/clients/jedis/JedisClusterTest.java index b93fa2409e..8297eb90c6 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTest.java @@ -741,6 +741,65 @@ public void clusterRefreshNodes() throws Exception { } } + @Test(timeout = 30_000) + public void clusterPeriodTopologyRefreshTest() throws Exception { + Set jedisClusterNode = new HashSet<>(); + jedisClusterNode.add(nodeInfo1); + jedisClusterNode.add(nodeInfo2); + jedisClusterNode.add(nodeInfo3); + + // we set topologyRefreshPeriod is 1s + Duration topologyRefreshPeriod = Duration.ofSeconds(1); + try (JedisCluster cluster = new JedisCluster(jedisClusterNode, DEFAULT_CLIENT_CONFIG, DEFAULT_POOL_CONFIG, + topologyRefreshPeriod, DEFAULT_REDIRECTIONS, Duration.ofSeconds(10))) { + assertEquals(3, cluster.getClusterNodes().size()); + cleanUp(); // cleanup and add node4 + + // at first, join node4 to cluster + node1.clusterMeet(LOCAL_IP, nodeInfo2.getPort()); + node1.clusterMeet(LOCAL_IP, nodeInfo3.getPort()); + node1.clusterMeet(LOCAL_IP, nodeInfo4.getPort()); + // split available slots across the three nodes + int slotsPerNode = CLUSTER_HASHSLOTS / 4; + int[] node1Slots = new int[slotsPerNode]; + int[] node2Slots = new int[slotsPerNode]; + int[] node3Slots = new int[slotsPerNode]; + int[] node4Slots = new int[slotsPerNode]; + for (int i = 0, slot1 = 0, slot2 = 0, slot3 = 0, slot4 = 0; i < CLUSTER_HASHSLOTS; i++) { + if (i < slotsPerNode) { + node1Slots[slot1++] = i; + } else if (i >= slotsPerNode && i < slotsPerNode*2) { + node2Slots[slot2++] = i; + } else if (i >= slotsPerNode*2 && i < slotsPerNode*3) { + node3Slots[slot3++] = i; + } else { + node4Slots[slot4++] = i; + } + } + + node1.clusterAddSlots(node1Slots); + node2.clusterAddSlots(node2Slots); + node3.clusterAddSlots(node3Slots); + node4.clusterAddSlots(node4Slots); + JedisClusterTestUtil.waitForClusterReady(node1, node2, node3, node4); + + // Now we just wait topologyRefreshPeriod * 3 (executor will delay) for cluster topology refresh (3 -> 4) + Thread.sleep(topologyRefreshPeriod.toMillis() * 3); + + assertEquals(4, cluster.getClusterNodes().size()); + String nodeKey4 = LOCAL_IP + ":" + nodeInfo4.getPort(); + assertTrue(cluster.getClusterNodes().keySet().contains(nodeKey4)); + + // make 4 nodes to 3 nodes + cleanUp(); + setUp(); + + // Now we just wait topologyRefreshPeriod * 3 (executor will delay) for cluster topology refresh (4 -> 3) + Thread.sleep(topologyRefreshPeriod.toMillis() * 3); + assertEquals(3, cluster.getClusterNodes().size()); + } + } + private static String getNodeServingSlotRange(String infoOutput) { // f4f3dc4befda352a4e0beccf29f5e8828438705d 127.0.0.1:7380 master - 0 // 1394372400827 0 connected 5461-10922 diff --git a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java index 6094575a54..0746c2d37c 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java @@ -77,10 +77,10 @@ protected void cleanUp() { node2.flushDB(); node3.flushDB(); node4.flushDB(); - node1.clusterReset(ClusterResetType.SOFT); - node2.clusterReset(ClusterResetType.SOFT); - node3.clusterReset(ClusterResetType.SOFT); - node4.clusterReset(ClusterResetType.SOFT); + node1.clusterReset(ClusterResetType.HARD); + node2.clusterReset(ClusterResetType.HARD); + node3.clusterReset(ClusterResetType.HARD); + node4.clusterReset(ClusterResetType.HARD); } @After diff --git a/src/test/java/redis/clients/jedis/JedisPubSubBaseTest.java b/src/test/java/redis/clients/jedis/JedisPubSubBaseTest.java new file mode 100644 index 0000000000..a7910bd6a3 --- /dev/null +++ b/src/test/java/redis/clients/jedis/JedisPubSubBaseTest.java @@ -0,0 +1,59 @@ +package redis.clients.jedis; + +import junit.framework.TestCase; +import redis.clients.jedis.util.SafeEncoder; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static redis.clients.jedis.Protocol.ResponseKeyword.MESSAGE; +import static redis.clients.jedis.Protocol.ResponseKeyword.SUBSCRIBE; + +public class JedisPubSubBaseTest extends TestCase { + + public void testProceed_givenThreadInterrupt_exitLoop() throws InterruptedException { + // setup + final JedisPubSubBase pubSub = new JedisPubSubBase() { + + @Override + public void onMessage(String channel, String message) { + fail("this should not happen when thread is interrupted"); + } + + @Override + protected String encode(byte[] raw) { + return SafeEncoder.encode(raw); + } + }; + + final Connection mockConnection = mock(Connection.class); + final List mockSubscribe = Arrays.asList( + SUBSCRIBE.getRaw(), "channel".getBytes(), 1L + ); + final List mockResponse = Arrays.asList( + MESSAGE.getRaw(), "channel".getBytes(), "message".getBytes() + ); + + when(mockConnection.getUnflushedObject()). + + thenReturn(mockSubscribe, mockResponse); + + + final CountDownLatch countDownLatch = new CountDownLatch(1); + // action + final Thread thread = new Thread(() -> { + Thread.currentThread().interrupt(); + pubSub.proceed(mockConnection, "channel"); + + countDownLatch.countDown(); + }); + thread.start(); + + assertTrue(countDownLatch.await(10, TimeUnit.MILLISECONDS)); + + } +} diff --git a/src/test/java/redis/clients/jedis/JedisShardedPubSubBaseTest.java b/src/test/java/redis/clients/jedis/JedisShardedPubSubBaseTest.java new file mode 100644 index 0000000000..fb1ecdd87a --- /dev/null +++ b/src/test/java/redis/clients/jedis/JedisShardedPubSubBaseTest.java @@ -0,0 +1,56 @@ +package redis.clients.jedis; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static redis.clients.jedis.Protocol.ResponseKeyword.SMESSAGE; +import static redis.clients.jedis.Protocol.ResponseKeyword.SSUBSCRIBE; + +public class JedisShardedPubSubBaseTest extends TestCase { + + public void testProceed_givenThreadInterrupt_exitLoop() throws InterruptedException { + // setup + final JedisShardedPubSubBase pubSub = new JedisShardedPubSubBase() { + + @Override + public void onSMessage(String channel, String message) { + fail("this should not happen when thread is interrupted"); + } + + @Override + protected String encode(byte[] raw) { + return new String(raw); + } + + }; + + final Connection mockConnection = mock(Connection.class); + final List mockSubscribe = Arrays.asList( + SSUBSCRIBE.getRaw(), "channel".getBytes(), 1L + ); + final List mockResponse = Arrays.asList( + SMESSAGE.getRaw(), "channel".getBytes(), "message".getBytes() + ); + when(mockConnection.getUnflushedObject()).thenReturn(mockSubscribe, mockResponse); + + + final CountDownLatch countDownLatch = new CountDownLatch(1); + // action + final Thread thread = new Thread(() -> { + Thread.currentThread().interrupt(); + pubSub.proceed(mockConnection, "channel"); + + countDownLatch.countDown(); + }); + thread.start(); + + assertTrue(countDownLatch.await(10, TimeUnit.MILLISECONDS)); + + } +} \ No newline at end of file diff --git a/src/test/java/redis/clients/jedis/JedisTest.java b/src/test/java/redis/clients/jedis/JedisTest.java index df56ea4fb2..e9520ff394 100644 --- a/src/test/java/redis/clients/jedis/JedisTest.java +++ b/src/test/java/redis/clients/jedis/JedisTest.java @@ -288,4 +288,39 @@ public void checkDisconnectOnQuit() { assertFalse(jedis.isConnected()); } + @Test + public void clientSetInfoDefault() { + try (Jedis jedis = new Jedis(hnp, DefaultJedisClientConfig.builder().password("foobared") + .clientSetInfoConfig(ClientSetInfoConfig.DEFAULT).build())) { + assertEquals("PONG", jedis.ping()); + String info = jedis.clientInfo(); + assertTrue(info.contains("lib-name=" + JedisMetaInfo.getArtifactId())); + assertTrue(info.contains("lib-ver=" + JedisMetaInfo.getVersion())); + } + } + + @Test + public void clientSetInfoDisabled() { + try (Jedis jedis = new Jedis(hnp, DefaultJedisClientConfig.builder().password("foobared") + .clientSetInfoConfig(ClientSetInfoConfig.DISABLED).build())) { + assertEquals("PONG", jedis.ping()); + String info = jedis.clientInfo(); + assertFalse(info.contains("lib-name=" + JedisMetaInfo.getArtifactId())); + assertFalse(info.contains("lib-ver=" + JedisMetaInfo.getVersion())); + } + } + + @Test + public void clientSetInfoLibNameSuffix() { + final String libNameSuffix = "for-redis"; + ClientSetInfoConfig setInfoConfig = ClientSetInfoConfig.withLibNameSuffix(libNameSuffix); + try (Jedis jedis = new Jedis(hnp, DefaultJedisClientConfig.builder().password("foobared") + .clientSetInfoConfig(setInfoConfig).build())) { + assertEquals("PONG", jedis.ping()); + String info = jedis.clientInfo(); + assertTrue(info.contains("lib-name=" + JedisMetaInfo.getArtifactId() + '(' + libNameSuffix + ')')); + assertTrue(info.contains("lib-ver=" + JedisMetaInfo.getVersion())); + } + } + } diff --git a/src/test/java/redis/clients/jedis/MigratePipeliningTest.java b/src/test/java/redis/clients/jedis/MigratePipeliningTest.java new file mode 100644 index 0000000000..b7942fc140 --- /dev/null +++ b/src/test/java/redis/clients/jedis/MigratePipeliningTest.java @@ -0,0 +1,398 @@ +package redis.clients.jedis; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.both; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasToString; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import redis.clients.jedis.commands.jedis.JedisCommandsTestBase; +import redis.clients.jedis.exceptions.JedisDataException; +import redis.clients.jedis.params.MigrateParams; + +public class MigratePipeliningTest extends JedisCommandsTestBase { + + private static final byte[] bfoo = { 0x01, 0x02, 0x03 }; + private static final byte[] bbar = { 0x04, 0x05, 0x06 }; + private static final byte[] bfoo1 = { 0x07, 0x08, 0x01 }; + private static final byte[] bbar1 = { 0x09, 0x00, 0x01 }; + private static final byte[] bfoo2 = { 0x07, 0x08, 0x02 }; + private static final byte[] bbar2 = { 0x09, 0x00, 0x02 }; + private static final byte[] bfoo3 = { 0x07, 0x08, 0x03 }; + private static final byte[] bbar3 = { 0x09, 0x00, 0x03 }; + + private static final String host = hnp.getHost(); + private static final int port = 6386; + private static final int portAuth = hnp.getPort() + 1; + private static final int db = 2; + private static final int dbAuth = 3; + private static final int timeout = Protocol.DEFAULT_TIMEOUT; + + private Jedis dest; + private Jedis destAuth; + + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + + dest = new Jedis(host, port, 500); + dest.flushAll(); + dest.select(db); + + destAuth = new Jedis(host, portAuth, 500); + destAuth.auth("foobared"); + destAuth.flushAll(); + destAuth.select(dbAuth); + } + + @After + @Override + public void tearDown() throws Exception { + dest.close(); + destAuth.close(); + super.tearDown(); + } + + @Test + public void noKey() { + Pipeline p = jedis.pipelined(); + + p.migrate(host, port, "foo", db, timeout); + p.migrate(host, port, bfoo, db, timeout); + p.migrate(host, port, db, timeout, new MigrateParams(), "foo1", "foo2", "foo3"); + p.migrate(host, port, db, timeout, new MigrateParams(), bfoo1, bfoo2, bfoo3); + + assertThat(p.syncAndReturnAll(), + hasItems("NOKEY", "NOKEY", "NOKEY", "NOKEY")); + } + + @Test + public void migrate() { + assertNull(dest.get("foo")); + + Pipeline p = jedis.pipelined(); + + p.set("foo", "bar"); + p.migrate(host, port, "foo", db, timeout); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertEquals("bar", dest.get("foo")); + } + + @Test + public void migrateBinary() { + assertNull(dest.get(bfoo)); + + Pipeline p = jedis.pipelined(); + + p.set(bfoo, bbar); + p.migrate(host, port, bfoo, db, timeout); + p.get(bfoo); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertArrayEquals(bbar, dest.get(bfoo)); + } + + @Test + public void migrateEmptyParams() { + assertNull(dest.get("foo")); + + Pipeline p = jedis.pipelined(); + + p.set("foo", "bar"); + p.migrate(host, port, db, timeout, new MigrateParams(), "foo"); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertEquals("bar", dest.get("foo")); + } + + @Test + public void migrateEmptyParamsBinary() { + assertNull(dest.get(bfoo)); + + Pipeline p = jedis.pipelined(); + + p.set(bfoo, bbar); + p.migrate(host, port, db, timeout, new MigrateParams(), bfoo); + p.get(bfoo); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertArrayEquals(bbar, dest.get(bfoo)); + } + + @Test + public void migrateCopy() { + assertNull(dest.get("foo")); + + Pipeline p = jedis.pipelined(); + + p.set("foo", "bar"); + p.migrate(host, port, db, timeout, new MigrateParams().copy(), "foo"); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", "bar")); + + assertEquals("bar", dest.get("foo")); + } + + @Test + public void migrateCopyBinary() { + assertNull(dest.get(bfoo)); + + Pipeline p = jedis.pipelined(); + + p.set(bfoo, bbar); + p.migrate(host, port, db, timeout, new MigrateParams().copy(), bfoo); + p.get(bfoo); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", bbar)); + + assertArrayEquals(bbar, dest.get(bfoo)); + } + + @Test + public void migrateReplace() { + dest.set("foo", "bar2"); + + assertEquals("bar2", dest.get("foo")); + + Pipeline p = jedis.pipelined(); + + p.set("foo", "bar1"); + p.migrate(host, port, db, timeout, new MigrateParams().replace(), "foo"); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertEquals("bar1", dest.get("foo")); + } + + @Test + public void migrateReplaceBinary() { + dest.set(bfoo, bbar2); + + assertArrayEquals(bbar2, dest.get(bfoo)); + + Pipeline p = jedis.pipelined(); + + p.set(bfoo, bbar1); + p.migrate(host, port, db, timeout, new MigrateParams().replace(), bfoo); + p.get(bfoo); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertArrayEquals(bbar1, dest.get(bfoo)); + } + + @Test + public void migrateCopyReplace() { + dest.set("foo", "bar2"); + + assertEquals("bar2", dest.get("foo")); + + Pipeline p = jedis.pipelined(); + + p.set("foo", "bar1"); + p.migrate(host, port, db, timeout, new MigrateParams().copy().replace(), "foo"); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", "bar1")); + + assertEquals("bar1", dest.get("foo")); + } + + @Test + public void migrateCopyReplaceBinary() { + dest.set(bfoo, bbar2); + + assertArrayEquals(bbar2, dest.get(bfoo)); + + Pipeline p = jedis.pipelined(); + + p.set(bfoo, bbar1); + p.migrate(host, port, db, timeout, new MigrateParams().copy().replace(), bfoo); + p.get(bfoo); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", bbar1)); + + assertArrayEquals(bbar1, dest.get(bfoo)); + } + + @Test + public void migrateAuth() { + assertNull(dest.get("foo")); + + Pipeline p = jedis.pipelined(); + + p.set("foo", "bar"); + p.migrate(host, portAuth, dbAuth, timeout, new MigrateParams().auth("foobared"), "foo"); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertEquals("bar", destAuth.get("foo")); + } + + @Test + public void migrateAuthBinary() { + assertNull(dest.get(bfoo)); + + Pipeline p = jedis.pipelined(); + + p.set(bfoo, bbar); + p.migrate(host, portAuth, dbAuth, timeout, new MigrateParams().auth("foobared"), bfoo); + p.get(bfoo); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertArrayEquals(bbar, destAuth.get(bfoo)); + } + + @Test + public void migrateAuth2() { + assertNull(jedis.get("foo")); + + Pipeline p = destAuth.pipelined(); + + p.set("foo", "bar"); + p.migrate(host, hnp.getPort(), 0, timeout, + new MigrateParams().auth2("acljedis", "fizzbuzz"), "foo"); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertEquals("bar", jedis.get("foo")); + } + + @Test + public void migrateAuth2Binary() { + assertNull(jedis.get(bfoo)); + + Pipeline p = dest.pipelined(); + + p.set(bfoo, bbar); + p.migrate(host, hnp.getPort(), 0, timeout, + new MigrateParams().auth2("acljedis", "fizzbuzz"), bfoo); + p.get(bfoo); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK", null)); + + assertArrayEquals(bbar, jedis.get(bfoo)); + } + + @Test + public void migrateMulti() { + assertNull(dest.get("foo1")); + assertNull(dest.get("foo2")); + assertNull(dest.get("foo3")); + + Pipeline p = jedis.pipelined(); + + p.mset("foo1", "bar1", "foo2", "bar2", "foo3", "bar3"); + p.migrate(host, port, db, timeout, new MigrateParams(), "foo1", "foo2", "foo3"); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK")); + + assertEquals("bar1", dest.get("foo1")); + assertEquals("bar2", dest.get("foo2")); + assertEquals("bar3", dest.get("foo3")); + } + + @Test + public void migrateMultiBinary() { + assertNull(dest.get(bfoo1)); + assertNull(dest.get(bfoo2)); + assertNull(dest.get(bfoo3)); + + Pipeline p = jedis.pipelined(); + + p.mset(bfoo1, bbar1, bfoo2, bbar2, bfoo3, bbar3); + p.migrate(host, port, db, timeout, new MigrateParams(), bfoo1, bfoo2, bfoo3); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "OK")); + + assertArrayEquals(bbar1, dest.get(bfoo1)); + assertArrayEquals(bbar2, dest.get(bfoo2)); + assertArrayEquals(bbar3, dest.get(bfoo3)); + } + + @Test + public void migrateConflict() { + dest.set("foo2", "bar"); + + assertNull(dest.get("foo1")); + assertEquals("bar", dest.get("foo2")); + assertNull(dest.get("foo3")); + + Pipeline p = jedis.pipelined(); + + p.mset("foo1", "bar1", "foo2", "bar2", "foo3", "bar3"); + p.migrate(host, port, db, timeout, new MigrateParams(), "foo1", "foo2", "foo3"); + + assertThat(p.syncAndReturnAll(), + hasItems( + equalTo("OK"), + both(instanceOf(JedisDataException.class)).and(hasToString(containsString("BUSYKEY"))) + )); + + assertEquals("bar1", dest.get("foo1")); + assertEquals("bar", dest.get("foo2")); + assertEquals("bar3", dest.get("foo3")); + } + + @Test + public void migrateConflictBinary() { + dest.set(bfoo2, bbar); + + assertNull(dest.get(bfoo1)); + assertArrayEquals(bbar, dest.get(bfoo2)); + assertNull(dest.get(bfoo3)); + + Pipeline p = jedis.pipelined(); + + p.mset(bfoo1, bbar1, bfoo2, bbar2, bfoo3, bbar3); + p.migrate(host, port, db, timeout, new MigrateParams(), bfoo1, bfoo2, bfoo3); + + assertThat(p.syncAndReturnAll(), + hasItems( + equalTo("OK"), + both(instanceOf(JedisDataException.class)).and(hasToString(containsString("BUSYKEY"))) + )); + + assertArrayEquals(bbar1, dest.get(bfoo1)); + assertArrayEquals(bbar, dest.get(bfoo2)); + assertArrayEquals(bbar3, dest.get(bfoo3)); + } + +} diff --git a/src/test/java/redis/clients/jedis/PipeliningTest.java b/src/test/java/redis/clients/jedis/PipeliningTest.java index bb9834c8d6..527b9dfc6d 100644 --- a/src/test/java/redis/clients/jedis/PipeliningTest.java +++ b/src/test/java/redis/clients/jedis/PipeliningTest.java @@ -1,5 +1,10 @@ package redis.clients.jedis; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.matchesPattern; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -16,18 +21,23 @@ import java.util.Set; import java.util.UUID; -import org.hamcrest.MatcherAssert; +import org.hamcrest.Matcher; import org.hamcrest.Matchers; import org.junit.Test; - -import redis.clients.jedis.exceptions.JedisDataException; -import redis.clients.jedis.resps.Tuple; +import redis.clients.jedis.commands.ProtocolCommand; import redis.clients.jedis.commands.jedis.JedisCommandsTestBase; +import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.params.SetParams; +import redis.clients.jedis.resps.Tuple; import redis.clients.jedis.util.SafeEncoder; public class PipeliningTest extends JedisCommandsTestBase { + private static final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; + private static final byte[] bfoo1 = { 0x01, 0x02, 0x03, 0x04, 0x11, 0x12, 0x13, 0x14 }; + private static final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 }; + private static final byte[] bbaz = { 0x09, 0x0A, 0x0B, 0x0C }; + @Test public void pipeline() { Pipeline p = jedis.pipelined(); @@ -271,150 +281,6 @@ public void piplineWithError() { } assertEquals(r.get(), "bar"); } -// -// @Test -// public void multi() { -// Pipeline p = jedis.pipelined(); -// p.multi(); -// Response r1 = p.hincrBy("a", "f1", -1); -// Response r2 = p.hincrBy("a", "f1", -2); -// Response> r3 = p.exec(); -// List result = p.syncAndReturnAll(); -// -// assertEquals(Long.valueOf(-1), r1.get()); -// assertEquals(Long.valueOf(-3), r2.get()); -// -// assertEquals(4, result.size()); -// -// assertEquals("OK", result.get(0)); -// assertEquals("QUEUED", result.get(1)); -// assertEquals("QUEUED", result.get(2)); -// -// // 4th result is a list with the results from the multi -// @SuppressWarnings("unchecked") -// List multiResult = (List) result.get(3); -// assertEquals(Long.valueOf(-1), multiResult.get(0)); -// assertEquals(Long.valueOf(-3), multiResult.get(1)); -// -// assertEquals(Long.valueOf(-1), r3.get().get(0)); -// assertEquals(Long.valueOf(-3), r3.get().get(1)); -// -// } -// -// @Test -// public void multiWithMassiveRequests() { -// Pipeline p = jedis.pipelined(); -// p.multi(); -// -// List> responseList = new ArrayList>(); -// for (int i = 0; i < 100000; i++) { -// // any operation should be ok, but shouldn't forget about timeout -// responseList.add(p.setbit("test", 1, true)); -// } -// -// Response> exec = p.exec(); -// p.sync(); -// -// // we don't need to check return value -// // if below codes run without throwing Exception, we're ok -// exec.get(); -// -// for (Response resp : responseList) { -// resp.get(); -// } -// } -// -// @Test -// public void multiWithSync() { -// jedis.set("foo", "314"); -// jedis.set("bar", "foo"); -// jedis.set("hello", "world"); -// Pipeline p = jedis.pipelined(); -// Response r1 = p.get("bar"); -// p.multi(); -// Response r2 = p.get("foo"); -// p.exec(); -// Response r3 = p.get("hello"); -// p.sync(); -// -// // before multi -// assertEquals("foo", r1.get()); -// // It should be readable whether exec's response was built or not -// assertEquals("314", r2.get()); -// // after multi -// assertEquals("world", r3.get()); -// } -// -// @Test -// public void multiWatch() { -// final String key = "foo"; -// assertEquals(5L, jedis.incrBy(key, 5L)); -// -// List expect = new ArrayList<>(); -// List expMulti = null; // MULTI will fail -// -// Pipeline pipe = jedis.pipelined(); -// pipe.watch(key); expect.add("OK"); -// pipe.incrBy(key, 3L); expect.add(8L); -// pipe.multi(); expect.add("OK"); -// pipe.incrBy(key, 6L); expect.add("QUEUED"); -// assertEquals(expect, pipe.syncAndReturnAll()); expect.clear(); -// -// try (Jedis tweak = createJedis()) { -// assertEquals(10L, tweak.incrBy(key, 2L)); -// } -// -// pipe.incrBy(key, 4L); expect.add("QUEUED"); -// pipe.exec(); expect.add(expMulti); // failed MULTI -// pipe.incrBy(key, 7L); expect.add(17L); -// assertEquals(expect, pipe.syncAndReturnAll()); -// } -// -// @Test -// public void multiUnwatch() { -// final String key = "foo"; -// assertEquals(5L, jedis.incrBy(key, 5L)); -// -// List expect = new ArrayList<>(); -// List expMulti = new ArrayList<>(); -// -// Pipeline pipe = jedis.pipelined(); -// pipe.watch(key); expect.add("OK"); -// pipe.incrBy(key, 3L); expect.add(8L); -// pipe.unwatch(); expect.add("OK"); -// pipe.multi(); expect.add("OK"); -// pipe.incrBy(key, 6L); expect.add("QUEUED"); expMulti.add(16L); -// assertEquals(expect, pipe.syncAndReturnAll()); expect.clear(); -// -// try (Jedis tweak = createJedis()) { -// assertEquals(10L, tweak.incrBy(key, 2L)); -// } -// -// pipe.incrBy(key, 4L); expect.add("QUEUED"); expMulti.add(20L); -// pipe.exec(); expect.add(expMulti); // successful MULTI -// pipe.incrBy(key, 7L); expect.add(27L); -// assertEquals(expect, pipe.syncAndReturnAll()); -// } -// -// @Test(expected = IllegalStateException.class) -// public void pipelineExecWhenNotInMulti() { -// Pipeline pipeline = jedis.pipelined(); -// pipeline.exec(); -// } -// -// @Test(expected = IllegalStateException.class) -// public void pipelineDiscardWhenNotInMulti() { -// Pipeline pipeline = jedis.pipelined(); -// pipeline.discard(); -// } -// -// @Test(expected = IllegalStateException.class) -// public void pipelineMultiWhenAlreadyInMulti() { -// Pipeline pipeline = jedis.pipelined(); -// pipeline.multi(); -// pipeline.set("foo", "3"); -// pipeline.multi(); -// } @Test(expected = IllegalStateException.class) public void testJedisThrowExceptionWhenInPipeline() { @@ -441,18 +307,6 @@ public void testResetStateWhenInPipeline() { String result = jedis.get("foo"); assertEquals(result, "3"); } -// -// @Test -// public void testDiscardInPipeline() { -// Pipeline pipeline = jedis.pipelined(); -// pipeline.multi(); -// pipeline.set("foo", "bar"); -// Response discard = pipeline.discard(); -// Response get = pipeline.get("foo"); -// pipeline.sync(); -// discard.get(); -// get.get(); -// } @Test public void waitReplicas() { @@ -581,8 +435,8 @@ public void testEvalNestedLists() { p.sync(); List results = (List) result.get(); - MatcherAssert.assertThat((List) results.get(0), Matchers.hasItem("key1")); - MatcherAssert.assertThat((List) results.get(1), Matchers.hasItem(2L)); + assertThat((List) results.get(0), Matchers.hasItem("key1")); + assertThat((List) results.get(1), Matchers.hasItem(2L)); } @Test @@ -595,8 +449,8 @@ public void testEvalNestedListsWithBinary() { p.sync(); List results = (List) result.get(); - MatcherAssert.assertThat((List) results.get(0), Matchers.hasItem(bKey)); - MatcherAssert.assertThat((List) results.get(1), Matchers.hasItem(2L)); + assertThat((List) results.get(0), Matchers.hasItem(bKey)); + assertThat((List) results.get(1), Matchers.hasItem(2L)); } @Test @@ -657,72 +511,6 @@ public void testEvalshaKeyAndArgWithBinary() { assertNull(result1.get()); assertArrayEquals(SafeEncoder.encode("13"), result2.get()); } -// -// @Test -// public void testPipelinedTransactionResponse() { -// -// String key1 = "key1"; -// String val1 = "val1"; -// -// String key2 = "key2"; -// String val2 = "val2"; -// -// String key3 = "key3"; -// String field1 = "field1"; -// String field2 = "field2"; -// String field3 = "field3"; -// String field4 = "field4"; -// -// String value1 = "value1"; -// String value2 = "value2"; -// String value3 = "value3"; -// String value4 = "value4"; -// -// Map hashMap = new HashMap(); -// hashMap.put(field1, value1); -// hashMap.put(field2, value2); -// -// String key4 = "key4"; -// Map hashMap1 = new HashMap(); -// hashMap1.put(field3, value3); -// hashMap1.put(field4, value4); -// -// jedis.set(key1, val1); -// jedis.set(key2, val2); -// jedis.hmset(key3, hashMap); -// jedis.hmset(key4, hashMap1); -// -// Pipeline pipeline = jedis.pipelined(); -// pipeline.multi(); -// -// pipeline.get(key1); -// pipeline.hgetAll(key2); -// pipeline.hgetAll(key3); -// pipeline.get(key4); -// -// Response> response = pipeline.exec(); -// pipeline.sync(); -// -// List result = response.get(); -// -// assertEquals(4, result.size()); -// -// assertEquals("val1", result.get(0)); -// -// assertTrue(result.get(1) instanceof JedisDataException); -// -// Map hashMapReceived = (Map) result.get(2); -// Iterator iterator = hashMapReceived.keySet().iterator(); -// String mapKey1 = iterator.next(); -// String mapKey2 = iterator.next(); -// assertFalse(iterator.hasNext()); -// verifyHasBothValues(mapKey1, mapKey2, field1, field2); -// String mapValue1 = hashMapReceived.get(mapKey1); -// String mapValue2 = hashMapReceived.get(mapKey2); -// verifyHasBothValues(mapValue1, mapValue2, value1, value2); -// -// assertTrue(result.get(3) instanceof JedisDataException); -// } @Test public void testSyncWithNoCommandQueued() { @@ -760,111 +548,148 @@ public void testCloseable() throws IOException { retFuture2.get(); jedis2.close(); } -// -// @Test -// public void testCloseableWithMulti() throws IOException { -// // we need to test with fresh instance of Jedis -// Jedis jedis2 = new Jedis(hnp.getHost(), hnp.getPort(), 500); -// jedis2.auth("foobared"); -// -// Pipeline pipeline = jedis2.pipelined(); -// Response retFuture1 = pipeline.set("a", "1"); -// Response retFuture2 = pipeline.set("b", "2"); -// -// pipeline.multi(); -// -// pipeline.set("a", "a"); -// pipeline.set("b", "b"); -// -// pipeline.close(); -// -// try { -// pipeline.exec(); -// fail("close should discard transaction"); -// } catch (IllegalStateException e) { -// assertTrue(e.getMessage().contains("EXEC without MULTI")); -// // pass -// } -// -// // it shouldn't meet any exception -// retFuture1.get(); -// retFuture2.get(); -// jedis2.close(); -// } -// -// @Test -// public void execAbort() { -// final String luaTimeLimitKey = "lua-time-limit"; -// final String luaTimeLimit = jedis.configGet(luaTimeLimitKey).get(1); -// jedis.configSet(luaTimeLimitKey, "10"); -// -// Thread thread = new Thread(() -> { -// try (Jedis blocker = createJedis()) { -// blocker.eval("while true do end"); -// } catch (Exception ex) { -// // swallow any exception -// } -// }); -// -// Pipeline pipe = jedis.pipelined(); -// pipe.incr("foo"); -// pipe.multi(); -// pipe.incr("foo"); -// pipe.sync(); -// -// thread.start(); -// try { -// Thread.sleep(12); // allow Redis to be busy with the script and 'lua-time-limit' to exceed -// } catch (InterruptedException ex) { } -// -// pipe.incr("foo"); -// Response> txResp = pipe.exec(); -// pipe.sync(); -// try { -// txResp.get(); -// } catch (Exception ex) { -// assertSame(AbortedTransactionException.class, ex.getClass()); -// } finally { -// try { -// String status = jedis.scriptKill(); -// // https://github.com/redis/jedis/issues/2656 -// if ("OK".equalsIgnoreCase(status)) { -// scriptKillWait(); -// } else { -// // #2656: Checking if this status is actually 'OK' when error occurs in next command. -// org.apache.logging.log4j.LogManager.getLogger().error( -// String.format("Status if SCRIPT KILL command is \"%s\"", status)); -// } -// } finally { -// jedis.configSet(luaTimeLimitKey, luaTimeLimit); -// } -// } -// } -// -// private void scriptKillWait() { -// int attemptLeft = 10; -// while (attemptLeft > 0) { -// try (Jedis pingJedis = createJedis()) { -// while (attemptLeft > 0) { -// try { -// pingJedis.ping(); -// return; // wait is over -// } catch (JedisBusyException busy) { -// Thread.sleep(10); // BUSY, waiting for some time -// --attemptLeft; // doing this later; otherwise any exception in Thread.sleep() -// // would cause decrement twice for the same turn. -// } -// } -// } catch (Exception any) { -// --attemptLeft; -// // try new connection -// } -// } -// } -// -// private void verifyHasBothValues(String firstKey, String secondKey, String value1, String value2) { -// assertFalse(firstKey.equals(secondKey)); -// assertTrue(firstKey.equals(value1) || firstKey.equals(value2)); -// assertTrue(secondKey.equals(value1) || secondKey.equals(value2)); -// } + + @Test + public void time() { + Pipeline p = jedis.pipelined(); + + p.time(); + + // we get back one result, with two components: the seconds, and the microseconds, but encoded as strings + Matcher timeResponseMatcher = hasItems(matchesPattern("\\d+"), matchesPattern("\\d+")); + assertThat(p.syncAndReturnAll(), + hasItems(timeResponseMatcher)); + } + + @Test + public void dbSize() { + Pipeline p = jedis.pipelined(); + + p.dbSize(); + p.set("foo", "bar"); + p.dbSize(); + + assertThat(p.syncAndReturnAll(), + hasItems(0L, "OK", 1L)); + } + + @Test + public void move() { + Pipeline p = jedis.pipelined(); + + p.move("foo", 1); + p.set("foo", "bar"); + p.move("foo", 1); + p.get("foo"); + p.select(1); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems(0L, "OK", 1L, null, "OK", "bar")); + } + + @Test + public void moveBinary() { + Pipeline p = jedis.pipelined(); + + p.move(bfoo, 1); + p.set(bfoo, bbar); + p.move(bfoo, 1); + p.get(bfoo); + p.select(1); + p.get(bfoo); + + assertThat(p.syncAndReturnAll(), + hasItems(0L, "OK", 1L, null, "OK", bbar)); + } + + @Test + public void swapDb() { + Pipeline p = jedis.pipelined(); + + p.set("foo", "bar"); + p.get("foo"); + p.select(1); + p.get("foo"); + p.swapDB(0, 1); + p.select(0); + p.get("foo"); + p.select(1); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems("OK", "bar", "OK", null, "OK", "OK", null, "OK", "bar")); + } + + @Test + public void copyToAnotherDb() { + Pipeline p = jedis.pipelined(); + + p.copy("foo", "foo-copy", 1, false); + p.set("foo", "bar"); + p.copy("foo", "foo-copy", 1, false); + p.get("foo"); + p.select(1); + p.get("foo-copy"); + p.select(0); + p.set("foo", "baz"); + p.copy("foo", "foo-copy", 1, false); + p.get("foo"); + p.select(1); + p.get("foo-copy"); + + assertThat(p.syncAndReturnAll(), + hasItems(false, "OK", true, "bar", "OK", "bar", "OK", "OK", false, "baz", "bar")); + } + + @Test + public void copyToAnotherDbBinary() { + Pipeline p = jedis.pipelined(); + + + p.copy(bfoo, bfoo1, 1, false); + p.set(bfoo, bbar); + p.copy(bfoo, bfoo1, 1, false); + p.get(bfoo); + p.select(1); + p.get(bfoo1); + p.select(0); + p.set(bfoo, bbaz); + p.copy(bfoo, bfoo1, 1, false); + p.get(bfoo); + p.select(1); + p.get(bfoo1); + + assertThat(p.syncAndReturnAll(), + hasItems(false, "OK", true, bbar, "OK", bbar, "OK", "OK", false, bbaz, bbar)); + } + + enum Foo implements ProtocolCommand { + FOO; + + @Override + public byte[] getRaw() { + return SafeEncoder.encode(name()); + } + } + + @Test + public void errorInTheMiddle() { + CommandObject invalidCommand = + new CommandObject<>(new CommandObjects().commandArguments(Foo.FOO), BuilderFactory.STRING); + + Pipeline p = jedis.pipelined(); + + p.set("foo", "bar"); + p.appendCommand(invalidCommand); + p.get("foo"); + + assertThat(p.syncAndReturnAll(), + hasItems( + equalTo("OK"), + instanceOf(JedisDataException.class), + equalTo("bar") + )); + } + } diff --git a/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java index fc3f4c9c3e..a681d4f4d8 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java @@ -21,6 +21,7 @@ import redis.clients.jedis.HostAndPort; import redis.clients.jedis.Jedis; +import redis.clients.jedis.Transaction; import redis.clients.jedis.args.ExpiryOption; import redis.clients.jedis.params.ScanParams; import redis.clients.jedis.resps.ScanResult; @@ -1124,4 +1125,32 @@ public void copy() { assertTrue(jedis.copy(bfoo1, bfoo2, true)); assertArrayEquals(bbar1, jedis.get(bfoo2)); } + + @Test + public void reset() { + // response test + String status = jedis.reset(); + assertEquals("RESET", status); + + // auth reset + String counter = "counter"; + Exception ex1 = assertThrows(JedisDataException.class, () -> { + jedis.set(counter, "1"); + }); + assertEquals("NOAUTH Authentication required.", ex1.getMessage()); + + // multi reset + jedis.auth("foobared"); + jedis.set(counter, "1"); + + Transaction trans = jedis.multi(); + trans.incr(counter); + jedis.reset(); + + Exception ex2 = assertThrows(JedisDataException.class, trans::exec); + assertEquals("EXECABORT Transaction discarded because of: NOAUTH Authentication required.", ex2.getMessage()); + + jedis.auth("foobared"); + assertEquals("1", jedis.get(counter)); + } } diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java index cbe04a5503..cf7760dbf4 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java @@ -64,14 +64,14 @@ public void nameBinary() { } @Test - public void clientSetInfoDefault() { - String libName = "jedis"; + public void clientSetInfoCommand() { + String libName = "Jedis::A-Redis-Java-library"; String libVersion = "999.999.999"; assertEquals("OK", client.clientSetInfo(ClientAttributeOption.LIB_NAME, libName)); assertEquals("OK", client.clientSetInfo(ClientAttributeOption.LIB_VER, libVersion)); String info = client.clientInfo(); - assertTrue(info.contains("lib-name=jedis")); - assertTrue(info.contains("lib-ver=999.999.999")); + assertTrue(info.contains("lib-name=" + libName)); + assertTrue(info.contains("lib-ver=" + libVersion)); } @Test @@ -222,10 +222,10 @@ public void killAddrIpPort() { @Test public void killUser() { - Jedis client2 = new Jedis(hnp.getHost(), hnp.getPort(), 500); client.aclSetUser("test_kill", "on", "+acl", ">password1"); - try { + try (Jedis client2 = new Jedis(hnp.getHost(), hnp.getPort(), 500)) { client2.auth("test_kill", "password1"); + assertEquals(1, jedis.clientKill(new ClientKillParams().user("test_kill"))); assertDisconnected(client2); } finally { @@ -233,6 +233,27 @@ public void killUser() { } } + @Test + public void killMaxAge() throws InterruptedException { + long maxAge = 2; + + // sleep twice the maxAge, to be sure + Thread.sleep(maxAge * 2 * 1000); + + try (Jedis client2 = new Jedis(hnp.getHost(), hnp.getPort(), 500)) { + client2.auth("foobared"); + + long killedClients = jedis.clientKill(new ClientKillParams().maxAge(maxAge)); + + // The reality is that some tests leak clients, so we can't assert + // on the exact number of killed clients. + assertTrue(killedClients > 0); + + assertDisconnected(client); + assertConnected(client2); + } + } + @Test public void clientInfo() { String info = client.clientInfo(); @@ -267,6 +288,10 @@ private void assertDisconnected(Jedis j) { } } + private void assertConnected(Jedis j) { + assertEquals("PONG", j.ping()); + } + private String findInClientList() { for (String clientInfo : jedis.clientList().split("\n")) { if (pattern.matcher(clientInfo).find()) { diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java index a6654b47ca..7e5c5db875 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java @@ -3,6 +3,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.List; @@ -13,6 +14,7 @@ import org.junit.After; import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import redis.clients.jedis.HostAndPort; @@ -20,6 +22,8 @@ import redis.clients.jedis.args.ClusterResetType; import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.exceptions.JedisDataException; +import redis.clients.jedis.resps.ClusterShardInfo; +import redis.clients.jedis.resps.ClusterShardNodeInfo; import redis.clients.jedis.util.JedisClusterCRC16; import redis.clients.jedis.util.JedisClusterTestUtil; @@ -48,8 +52,17 @@ public void tearDown() { node2.disconnect(); } + @BeforeClass + public static void resetRedisBefore() { + removeSlots(); + } + @AfterClass - public static void removeSlots() throws InterruptedException { + public static void resetRedisAfter() { + removeSlots(); + } + + public static void removeSlots() { try (Jedis node = new Jedis(nodeInfo1)) { node.auth("cluster"); node.clusterReset(ClusterResetType.SOFT); @@ -189,6 +202,37 @@ public void clusterSlots() { node1.clusterDelSlots(3000, 3001, 3002); } + @Test + public void clusterShards() { + assertEquals("OK", node1.clusterAddSlots(3100, 3101, 3102, 3105)); + + List shards = node1.clusterShards(); + assertNotNull(shards); + assertTrue(shards.size() > 0); + + for (ClusterShardInfo shardInfo : shards) { + assertNotNull(shardInfo); + + assertTrue(shardInfo.getSlots().size() > 1); + for (List slotRange : shardInfo.getSlots()) { + assertEquals(2, slotRange.size()); + } + + for (ClusterShardNodeInfo nodeInfo : shardInfo.getNodes()) { + assertNotNull(nodeInfo.getId()); + assertNotNull(nodeInfo.getEndpoint()); + assertNotNull(nodeInfo.getIp()); + assertNull(nodeInfo.getHostname()); + assertNotNull(nodeInfo.getPort()); + assertNull(nodeInfo.getTlsPort()); + assertNotNull(nodeInfo.getRole()); + assertNotNull(nodeInfo.getReplicationOffset()); + assertNotNull(nodeInfo.getHealth()); + } + } + node1.clusterDelSlots(3100, 3101, 3102, 3105); + } + @Test public void clusterLinks() throws InterruptedException { List> links = node1.clusterLinks(); @@ -238,4 +282,4 @@ public void ClusterBumpEpoch() { MatcherAssert.assertThat(node1.clusterBumpEpoch(), Matchers.matchesPattern("^BUMPED|STILL [0-9]+$")); } -} \ No newline at end of file +} diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterScriptingCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterScriptingCommandsTest.java index a2304bc38c..503337683e 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterScriptingCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterScriptingCommandsTest.java @@ -1,6 +1,8 @@ package redis.clients.jedis.commands.jedis; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import java.util.ArrayList; @@ -8,10 +10,11 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.function.Supplier; import org.junit.Test; +import redis.clients.jedis.HostAndPort; import redis.clients.jedis.args.FlushMode; +import redis.clients.jedis.exceptions.JedisBroadcastException; import redis.clients.jedis.exceptions.JedisClusterOperationException; import redis.clients.jedis.exceptions.JedisDataException; @@ -110,4 +113,17 @@ public void broadcast() { assertEquals(Arrays.asList(false, false), cluster.scriptExists(Arrays.asList(sha1_1, sha1_2))); } + + @Test + public void broadcastWithError() { + + JedisBroadcastException error = assertThrows(JedisBroadcastException.class, () -> cluster.functionDelete("xyz")); + + Map replies = error.getReplies(); + assertEquals(3, replies.size()); + replies.values().forEach(r -> { + assertSame(JedisDataException.class, r.getClass()); + assertEquals("ERR Library not found", ((JedisDataException) r).getMessage()); + }); + } } diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java index df3fef6886..cb95a9489b 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java @@ -30,12 +30,15 @@ import redis.clients.jedis.JedisMonitor; import redis.clients.jedis.Protocol; import redis.clients.jedis.args.ClientPauseMode; +import redis.clients.jedis.args.LatencyEvent; import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.params.CommandListFilterByParams; import redis.clients.jedis.params.LolwutParams; import redis.clients.jedis.resps.CommandDocument; import redis.clients.jedis.resps.CommandInfo; +import redis.clients.jedis.resps.LatencyHistoryInfo; +import redis.clients.jedis.resps.LatencyLatestInfo; import redis.clients.jedis.util.AssertUtil; import redis.clients.jedis.util.KeyValue; import redis.clients.jedis.util.SafeEncoder; @@ -440,6 +443,23 @@ public void latencyDoctor() { assertNotNull(report); } + @Test + public void latencyLatest() { + Map report = jedis.latencyLatest(); + assertNotNull(report); + } + + @Test + public void latencyHistoryFork() { + List report = jedis.latencyHistory(LatencyEvent.FORK); + assertNotNull(report); + } + + @Test + public void latencyReset() { + assertTrue(jedis.latencyReset() >= 0); + } + @Test public void commandCount() { assertTrue(jedis.commandCount() > 100); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java index c592d65afa..a30740dcf6 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java @@ -1,5 +1,7 @@ package redis.clients.jedis.commands.jedis; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -10,6 +12,7 @@ import static redis.clients.jedis.params.ScanParams.SCAN_POINTER_START_BINARY; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -17,6 +20,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.junit.Test; @@ -339,13 +343,20 @@ public void hgetAllPipeline() { @Test public void hscan() { - jedis.hset("foo", "b", "b"); - jedis.hset("foo", "a", "a"); + jedis.hset("foo", "b", "y"); + jedis.hset("foo", "a", "x"); ScanResult> result = jedis.hscan("foo", SCAN_POINTER_START); assertEquals(SCAN_POINTER_START, result.getCursor()); - assertFalse(result.getResult().isEmpty()); + assertEquals(2, result.getResult().size()); + + assertThat( + result.getResult().stream().map(Map.Entry::getKey).collect(Collectors.toList()), + containsInAnyOrder("a", "b")); + assertThat( + result.getResult().stream().map(Map.Entry::getValue).collect(Collectors.toList()), + containsInAnyOrder("x", "y")); // binary jedis.hset(bfoo, bbar, bcar); @@ -353,7 +364,14 @@ public void hscan() { ScanResult> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY); assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes()); - assertFalse(bResult.getResult().isEmpty()); + assertEquals(1, bResult.getResult().size()); + + assertThat( + bResult.getResult().stream().map(Map.Entry::getKey).collect(Collectors.toList()), + containsInAnyOrder(bbar)); + assertThat( + bResult.getResult().stream().map(Map.Entry::getValue).collect(Collectors.toList()), + containsInAnyOrder(bcar)); } @Test @@ -361,13 +379,20 @@ public void hscanMatch() { ScanParams params = new ScanParams(); params.match("a*"); - jedis.hset("foo", "b", "b"); - jedis.hset("foo", "a", "a"); - jedis.hset("foo", "aa", "aa"); + jedis.hset("foo", "b", "y"); + jedis.hset("foo", "a", "x"); + jedis.hset("foo", "aa", "xx"); ScanResult> result = jedis.hscan("foo", SCAN_POINTER_START, params); assertEquals(SCAN_POINTER_START, result.getCursor()); - assertFalse(result.getResult().isEmpty()); + assertEquals(2, result.getResult().size()); + + assertThat( + result.getResult().stream().map(Map.Entry::getKey).collect(Collectors.toList()), + containsInAnyOrder("a", "aa")); + assertThat( + result.getResult().stream().map(Map.Entry::getValue).collect(Collectors.toList()), + containsInAnyOrder("x", "xx")); // binary params = new ScanParams(); @@ -379,10 +404,17 @@ public void hscanMatch() { jedis.hset(bfoo, bbar3, bcar); ScanResult> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, - params); + params); assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes()); - assertFalse(bResult.getResult().isEmpty()); + assertEquals(4, bResult.getResult().size()); + + assertThat( + bResult.getResult().stream().map(Map.Entry::getKey).collect(Collectors.toList()), + containsInAnyOrder(bbar, bbar1, bbar2, bbar3)); + assertThat( + bResult.getResult().stream().map(Map.Entry::getValue).collect(Collectors.toList()), + containsInAnyOrder(bcar, bcar, bcar, bcar)); } @Test @@ -391,13 +423,20 @@ public void hscanCount() { params.count(2); for (int i = 0; i < 10; i++) { - jedis.hset("foo", "a" + i, "a" + i); + jedis.hset("foo", "a" + i, "x" + i); } ScanResult> result = jedis.hscan("foo", SCAN_POINTER_START, params); assertFalse(result.getResult().isEmpty()); + assertThat( + result.getResult().stream().map(Map.Entry::getKey).map(s -> s.substring(0, 1)).collect(Collectors.toSet()), + containsInAnyOrder("a")); + assertThat( + result.getResult().stream().map(Map.Entry::getValue).map(s -> s.substring(0, 1)).collect(Collectors.toSet()), + containsInAnyOrder("x")); + // binary params = new ScanParams(); params.count(2); @@ -407,10 +446,109 @@ public void hscanCount() { jedis.hset(bfoo, bbar2, bcar); jedis.hset(bfoo, bbar3, bcar); - ScanResult> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, - params); + ScanResult> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, params); + + assertFalse(bResult.getResult().isEmpty()); + + assertThat( + bResult.getResult().stream().map(Map.Entry::getKey) + .map(a -> Arrays.copyOfRange(a, 0, 4)).map(Arrays::toString).collect(Collectors.toSet()), + containsInAnyOrder(Arrays.toString(bbar))); + assertThat( + bResult.getResult().stream().map(Map.Entry::getValue) + .map(a -> Arrays.copyOfRange(a, 0, 4)).map(Arrays::toString).collect(Collectors.toSet()), + containsInAnyOrder(Arrays.toString(bcar))); + } + + @Test + public void hscanNoValues() { + jedis.hset("foo", "b", "y"); + jedis.hset("foo", "a", "x"); + + ScanResult result = jedis.hscanNoValues("foo", SCAN_POINTER_START); + + assertEquals(SCAN_POINTER_START, result.getCursor()); + assertEquals(2, result.getResult().size()); + + assertThat(result.getResult(), containsInAnyOrder("a", "b")); + + // binary + jedis.hset(bfoo, bbar, bcar); + + ScanResult bResult = jedis.hscanNoValues(bfoo, SCAN_POINTER_START_BINARY); + + assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes()); + assertEquals(1, bResult.getResult().size()); + + assertThat(bResult.getResult(), containsInAnyOrder(bbar)); + } + + @Test + public void hscanNoValuesMatch() { + ScanParams params = new ScanParams(); + params.match("a*"); + + jedis.hset("foo", "b", "y"); + jedis.hset("foo", "a", "x"); + jedis.hset("foo", "aa", "xx"); + ScanResult result = jedis.hscanNoValues("foo", SCAN_POINTER_START, params); + + assertEquals(SCAN_POINTER_START, result.getCursor()); + assertEquals(2, result.getResult().size()); + + assertThat(result.getResult(), containsInAnyOrder("a", "aa")); + + // binary + params = new ScanParams(); + params.match(bbarstar); + + jedis.hset(bfoo, bbar, bcar); + jedis.hset(bfoo, bbar1, bcar); + jedis.hset(bfoo, bbar2, bcar); + jedis.hset(bfoo, bbar3, bcar); + + ScanResult bResult = jedis.hscanNoValues(bfoo, SCAN_POINTER_START_BINARY, params); + + assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes()); + assertEquals(4, bResult.getResult().size()); + + assertThat(bResult.getResult(), containsInAnyOrder(bbar, bbar1, bbar2, bbar3)); + } + + @Test + public void hscanNoValuesCount() { + ScanParams params = new ScanParams(); + params.count(2); + + for (int i = 0; i < 10; i++) { + jedis.hset("foo", "a" + i, "a" + i); + } + + ScanResult result = jedis.hscanNoValues("foo", SCAN_POINTER_START, params); + + assertFalse(result.getResult().isEmpty()); + + assertThat( + result.getResult().stream().map(s -> s.substring(0, 1)).collect(Collectors.toSet()), + containsInAnyOrder("a")); + + // binary + params = new ScanParams(); + params.count(2); + + jedis.hset(bfoo, bbar, bcar); + jedis.hset(bfoo, bbar1, bcar); + jedis.hset(bfoo, bbar2, bcar); + jedis.hset(bfoo, bbar3, bcar); + + ScanResult bResult = jedis.hscanNoValues(bfoo, SCAN_POINTER_START_BINARY, params); assertFalse(bResult.getResult().isEmpty()); + + assertThat( + bResult.getResult().stream() + .map(a -> Arrays.copyOfRange(a, 0, 4)).map(Arrays::toString).collect(Collectors.toSet()), + containsInAnyOrder(Arrays.toString(bbar))); } @Test diff --git a/src/test/java/redis/clients/jedis/commands/unified/HashesCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/HashesCommandsTestBase.java index cac2606984..d06edf38ec 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/HashesCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/HashesCommandsTestBase.java @@ -1,9 +1,10 @@ package redis.clients.jedis.commands.unified; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNull; @@ -11,6 +12,7 @@ import static redis.clients.jedis.params.ScanParams.SCAN_POINTER_START_BINARY; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -18,6 +20,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.junit.Test; @@ -316,13 +319,20 @@ public void hgetAll() { @Test public void hscan() { - jedis.hset("foo", "b", "b"); - jedis.hset("foo", "a", "a"); + jedis.hset("foo", "b", "y"); + jedis.hset("foo", "a", "x"); ScanResult> result = jedis.hscan("foo", SCAN_POINTER_START); assertEquals(SCAN_POINTER_START, result.getCursor()); - assertFalse(result.getResult().isEmpty()); + assertEquals(2, result.getResult().size()); + + assertThat( + result.getResult().stream().map(Map.Entry::getKey).collect(Collectors.toList()), + containsInAnyOrder("a", "b")); + assertThat( + result.getResult().stream().map(Map.Entry::getValue).collect(Collectors.toList()), + containsInAnyOrder("x", "y")); // binary jedis.hset(bfoo, bbar, bcar); @@ -330,7 +340,14 @@ public void hscan() { ScanResult> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY); assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes()); - assertFalse(bResult.getResult().isEmpty()); + assertEquals(1, bResult.getResult().size()); + + assertThat( + bResult.getResult().stream().map(Map.Entry::getKey).collect(Collectors.toList()), + containsInAnyOrder(bbar)); + assertThat( + bResult.getResult().stream().map(Map.Entry::getValue).collect(Collectors.toList()), + containsInAnyOrder(bcar)); } @Test @@ -338,13 +355,20 @@ public void hscanMatch() { ScanParams params = new ScanParams(); params.match("a*"); - jedis.hset("foo", "b", "b"); - jedis.hset("foo", "a", "a"); - jedis.hset("foo", "aa", "aa"); + jedis.hset("foo", "b", "y"); + jedis.hset("foo", "a", "x"); + jedis.hset("foo", "aa", "xx"); ScanResult> result = jedis.hscan("foo", SCAN_POINTER_START, params); assertEquals(SCAN_POINTER_START, result.getCursor()); - assertFalse(result.getResult().isEmpty()); + assertEquals(2, result.getResult().size()); + + assertThat( + result.getResult().stream().map(Map.Entry::getKey).collect(Collectors.toList()), + containsInAnyOrder("a", "aa")); + assertThat( + result.getResult().stream().map(Map.Entry::getValue).collect(Collectors.toList()), + containsInAnyOrder("x", "xx")); // binary params = new ScanParams(); @@ -355,11 +379,17 @@ public void hscanMatch() { jedis.hset(bfoo, bbar2, bcar); jedis.hset(bfoo, bbar3, bcar); - ScanResult> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, - params); + ScanResult> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, params); assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes()); - assertFalse(bResult.getResult().isEmpty()); + assertEquals(4, bResult.getResult().size()); + + assertThat( + bResult.getResult().stream().map(Map.Entry::getKey).collect(Collectors.toList()), + containsInAnyOrder(bbar, bbar1, bbar2, bbar3)); + assertThat( + bResult.getResult().stream().map(Map.Entry::getValue).collect(Collectors.toList()), + containsInAnyOrder(bcar, bcar, bcar, bcar)); } @Test @@ -368,13 +398,20 @@ public void hscanCount() { params.count(2); for (int i = 0; i < 10; i++) { - jedis.hset("foo", "a" + i, "a" + i); + jedis.hset("foo", "a" + i, "x" + i); } ScanResult> result = jedis.hscan("foo", SCAN_POINTER_START, params); assertFalse(result.getResult().isEmpty()); + assertThat( + result.getResult().stream().map(Map.Entry::getKey).map(s -> s.substring(0, 1)).collect(Collectors.toSet()), + containsInAnyOrder("a")); + assertThat( + result.getResult().stream().map(Map.Entry::getValue).map(s -> s.substring(0, 1)).collect(Collectors.toSet()), + containsInAnyOrder("x")); + // binary params = new ScanParams(); params.count(2); @@ -384,10 +421,109 @@ public void hscanCount() { jedis.hset(bfoo, bbar2, bcar); jedis.hset(bfoo, bbar3, bcar); - ScanResult> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, - params); + ScanResult> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, params); assertFalse(bResult.getResult().isEmpty()); + + assertThat( + bResult.getResult().stream().map(Map.Entry::getKey) + .map(a -> Arrays.copyOfRange(a, 0, 4)).map(Arrays::toString).collect(Collectors.toSet()), + containsInAnyOrder(Arrays.toString(bbar))); + assertThat( + bResult.getResult().stream().map(Map.Entry::getValue) + .map(a -> Arrays.copyOfRange(a, 0, 4)).map(Arrays::toString).collect(Collectors.toSet()), + containsInAnyOrder(Arrays.toString(bcar))); + } + + @Test + public void hscanNoValues() { + jedis.hset("foo", "b", "y"); + jedis.hset("foo", "a", "x"); + + ScanResult result = jedis.hscanNoValues("foo", SCAN_POINTER_START); + + assertEquals(SCAN_POINTER_START, result.getCursor()); + assertEquals(2, result.getResult().size()); + + assertThat(result.getResult(), containsInAnyOrder("a", "b")); + + // binary + jedis.hset(bfoo, bbar, bcar); + + ScanResult bResult = jedis.hscanNoValues(bfoo, SCAN_POINTER_START_BINARY); + + assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes()); + assertEquals(1, bResult.getResult().size()); + + assertThat(bResult.getResult(), containsInAnyOrder(bbar)); + } + + @Test + public void hscanNoValuesMatch() { + ScanParams params = new ScanParams(); + params.match("a*"); + + jedis.hset("foo", "b", "y"); + jedis.hset("foo", "a", "x"); + jedis.hset("foo", "aa", "xx"); + ScanResult result = jedis.hscanNoValues("foo", SCAN_POINTER_START, params); + + assertEquals(SCAN_POINTER_START, result.getCursor()); + assertEquals(2, result.getResult().size()); + + assertThat(result.getResult(), containsInAnyOrder("a", "aa")); + + // binary + params = new ScanParams(); + params.match(bbarstar); + + jedis.hset(bfoo, bbar, bcar); + jedis.hset(bfoo, bbar1, bcar); + jedis.hset(bfoo, bbar2, bcar); + jedis.hset(bfoo, bbar3, bcar); + + ScanResult bResult = jedis.hscanNoValues(bfoo, SCAN_POINTER_START_BINARY, params); + + assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes()); + assertEquals(4, bResult.getResult().size()); + + assertThat(bResult.getResult(), containsInAnyOrder(bbar, bbar1, bbar2, bbar3)); + } + + @Test + public void hscanNoValuesCount() { + ScanParams params = new ScanParams(); + params.count(2); + + for (int i = 0; i < 10; i++) { + jedis.hset("foo", "a" + i, "a" + i); + } + + ScanResult result = jedis.hscanNoValues("foo", SCAN_POINTER_START, params); + + assertFalse(result.getResult().isEmpty()); + + assertThat( + result.getResult().stream().map(s -> s.substring(0, 1)).collect(Collectors.toSet()), + containsInAnyOrder("a")); + + // binary + params = new ScanParams(); + params.count(2); + + jedis.hset(bfoo, bbar, bcar); + jedis.hset(bfoo, bbar1, bcar); + jedis.hset(bfoo, bbar2, bcar); + jedis.hset(bfoo, bbar3, bcar); + + ScanResult bResult = jedis.hscanNoValues(bfoo, SCAN_POINTER_START_BINARY, params); + + assertFalse(bResult.getResult().isEmpty()); + + assertThat( + bResult.getResult().stream() + .map(a -> Arrays.copyOfRange(a, 0, 4)).map(Arrays::toString).collect(Collectors.toSet()), + containsInAnyOrder(Arrays.toString(bbar))); } @Test diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledPipeliningTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java similarity index 73% rename from src/test/java/redis/clients/jedis/commands/unified/pooled/PooledPipeliningTest.java rename to src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java index da2c3f8846..fc917e4e47 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledPipeliningTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java @@ -1,6 +1,7 @@ package redis.clients.jedis.commands.unified.pooled; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import java.util.ArrayList; import java.util.Arrays; @@ -14,14 +15,14 @@ import redis.clients.jedis.JedisPooled; import redis.clients.jedis.Pipeline; import redis.clients.jedis.Response; -import redis.clients.jedis.Transaction; - +import redis.clients.jedis.AbstractTransaction; import redis.clients.jedis.commands.unified.UnifiedJedisCommandsTestBase; +import redis.clients.jedis.exceptions.JedisDataException; -public class PooledPipeliningTest extends UnifiedJedisCommandsTestBase { +public class PooledMiscellaneousTest extends UnifiedJedisCommandsTestBase { protected Pipeline pipeline; - protected Transaction transaction; + protected AbstractTransaction transaction; @BeforeClass public static void prepare() throws InterruptedException { @@ -47,7 +48,7 @@ public void tearDown() { } @Test - public void simple() { + public void pipeline() { final int count = 10; int totalCount = 0; for (int i = 0; i < count; i++) { @@ -104,4 +105,27 @@ public void transaction() { assertEquals(expected.get(i), responses.get(i)); } } + + @Test + public void broadcast() { + + String script_1 = "return 'jedis'"; + String sha1_1 = jedis.scriptLoad(script_1); + + String script_2 = "return 79"; + String sha1_2 = jedis.scriptLoad(script_2); + + assertEquals(Arrays.asList(true, true), jedis.scriptExists(Arrays.asList(sha1_1, sha1_2))); + + jedis.scriptFlush(); + + assertEquals(Arrays.asList(false, false), jedis.scriptExists(Arrays.asList(sha1_1, sha1_2))); + } + + @Test + public void broadcastWithError() { + JedisDataException error = assertThrows(JedisDataException.class, + () -> jedis.functionDelete("xyz")); + assertEquals("ERR Library not found", error.getMessage()); + } } diff --git a/src/test/java/redis/clients/jedis/examples/GeoShapeFieldsUsageInRediSearch.java b/src/test/java/redis/clients/jedis/examples/GeoShapeFieldsUsageInRediSearch.java new file mode 100644 index 0000000000..fd309def50 --- /dev/null +++ b/src/test/java/redis/clients/jedis/examples/GeoShapeFieldsUsageInRediSearch.java @@ -0,0 +1,107 @@ +package redis.clients.jedis.examples; + +import java.util.Collections; +import org.junit.Assert; + +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKTReader; + +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.UnifiedJedis; +import redis.clients.jedis.search.FTSearchParams; +import redis.clients.jedis.search.RediSearchUtil; +import redis.clients.jedis.search.SearchResult; +import redis.clients.jedis.search.schemafields.GeoShapeField; + +/** + * As of RediSearch 2.8.4, advanced GEO querying with GEOSHAPE fields is supported. + * + * Any object/library producing a + * well-known + * text (WKT) in {@code toString()} method can be used. + * + * This example uses the JTS library. + *
+ * {@code
+ * 
+ *   org.locationtech.jts
+ *   jts-core
+ *   1.19.0
+ * 
+ * }
+ * 
+ */ +public class GeoShapeFieldsUsageInRediSearch { + + public static void main(String[] args) { + + // We'll create geometry objects with GeometryFactory + final GeometryFactory factory = new GeometryFactory(); + + final String host = "localhost"; + final int port = 6379; + final HostAndPort address = new HostAndPort(host, port); + + UnifiedJedis client = new JedisPooled(address); + // client.setDefaultSearchDialect(3); // we can set default search dialect for the client (UnifiedJedis) object + // to avoid setting dialect in every query. + + // creating index + client.ftCreate("geometry-index", + GeoShapeField.of("geometry", GeoShapeField.CoordinateSystem.SPHERICAL) // 'SPHERICAL' is for geographic (lon, lat). + // 'FLAT' coordinate system also available for cartesian (X,Y). + ); + + // preparing data + final Polygon small = factory.createPolygon( + new Coordinate[]{new Coordinate(34.9001, 29.7001), + new Coordinate(34.9001, 29.7100), new Coordinate(34.9100, 29.7100), + new Coordinate(34.9100, 29.7001), new Coordinate(34.9001, 29.7001)} + ); + + // client.hset("small", RediSearchUtil.toStringMap(Collections.singletonMap("geometry", small))); // setting data + client.hset("small", "geometry", small.toString()); // simplified setting data + + final Polygon large = factory.createPolygon( + new Coordinate[]{new Coordinate(34.9001, 29.7001), + new Coordinate(34.9001, 29.7200), new Coordinate(34.9200, 29.7200), + new Coordinate(34.9200, 29.7001), new Coordinate(34.9001, 29.7001)} + ); + + // client.hset("large", RediSearchUtil.toStringMap(Collections.singletonMap("geometry", large))); // setting data + client.hset("large", "geometry", large.toString()); // simplified setting data + + // searching + final Polygon within = factory.createPolygon( + new Coordinate[]{new Coordinate(34.9000, 29.7000), + new Coordinate(34.9000, 29.7150), new Coordinate(34.9150, 29.7150), + new Coordinate(34.9150, 29.7000), new Coordinate(34.9000, 29.7000)} + ); + + SearchResult res = client.ftSearch("geometry-index", + "@geometry:[within $poly]", // querying 'within' condition. + // RediSearch also supports 'contains' condition. + FTSearchParams.searchParams() + .addParam("poly", within) + .dialect(3) // DIALECT '3' is required for this query + ); + Assert.assertEquals(1, res.getTotalResults()); + Assert.assertEquals(1, res.getDocuments().size()); + + // We can parse geometry objects with WKTReader + try { + final WKTReader reader = new WKTReader(); + Geometry object = reader.read(res.getDocuments().get(0).getString("geometry")); + Assert.assertEquals(small, object); + } catch (ParseException ex) { + ex.printStackTrace(System.err); + } + } + + // Note: As of RediSearch 2.8.4, only POLYGON and POINT objects are supported. +} diff --git a/src/test/java/redis/clients/jedis/exceptions/ExceptionsTest.java b/src/test/java/redis/clients/jedis/exceptions/ExceptionsTest.java index 9bdd77371b..4b1bef38fe 100644 --- a/src/test/java/redis/clients/jedis/exceptions/ExceptionsTest.java +++ b/src/test/java/redis/clients/jedis/exceptions/ExceptionsTest.java @@ -19,33 +19,6 @@ public static void prepare() { CAUSE = new Throwable("This is a test cause."); } - @Test - public void abortedTransaction() { - try { - throw new AbortedTransactionException(MESSAGE); - } catch (Exception e) { - assertSame(AbortedTransactionException.class, e.getClass()); - assertEquals(MESSAGE, e.getMessage()); - assertNull(e.getCause()); - } - - try { - throw new AbortedTransactionException(CAUSE); - } catch (Exception e) { - assertSame(AbortedTransactionException.class, e.getClass()); - assertEquals(CAUSE, e.getCause()); - assertEquals(CAUSE.toString(), e.getMessage()); - } - - try { - throw new AbortedTransactionException(MESSAGE, CAUSE); - } catch (Exception e) { - assertSame(AbortedTransactionException.class, e.getClass()); - assertEquals(MESSAGE, e.getMessage()); - assertEquals(CAUSE, e.getCause()); - } - } - @Test public void invalidURI() { try { diff --git a/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java b/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java new file mode 100644 index 0000000000..c6b25d764b --- /dev/null +++ b/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java @@ -0,0 +1,207 @@ +package redis.clients.jedis.misc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import redis.clients.jedis.AbstractPipeline; +import redis.clients.jedis.AbstractTransaction; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.HostAndPorts; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisClientConfig; +import redis.clients.jedis.MultiClusterClientConfig; +import redis.clients.jedis.UnifiedJedis; +import redis.clients.jedis.exceptions.JedisAccessControlException; +import redis.clients.jedis.exceptions.JedisConnectionException; +import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider; +import redis.clients.jedis.util.IOUtils; + +public class AutomaticFailoverTest { + + private static final Logger log = LoggerFactory.getLogger(AutomaticFailoverTest.class); + + private final HostAndPort hostPort_1 = new HostAndPort(HostAndPorts.getRedisServers().get(0).getHost(), 6378); + private final HostAndPort hostPort_1_2 = HostAndPorts.getRedisServers().get(0); + private final HostAndPort hostPort_2 = HostAndPorts.getRedisServers().get(7); + + private final JedisClientConfig clientConfig = DefaultJedisClientConfig.builder().build(); + + private Jedis jedis2; + + private List getClusterConfigs( + JedisClientConfig clientConfig, HostAndPort... hostPorts) { + return Arrays.stream(hostPorts) + .map(hp -> new MultiClusterClientConfig.ClusterConfig(hp, clientConfig)) + .collect(Collectors.toList()); + } + + @Before + public void setUp() { + jedis2 = new Jedis(hostPort_2, clientConfig); + jedis2.flushAll(); + } + + @After + public void cleanUp() { + IOUtils.closeQuietly(jedis2); + } + + @Test + public void pipelineWithSwitch() { + MultiClusterPooledConnectionProvider provider = new MultiClusterPooledConnectionProvider( + new MultiClusterClientConfig.Builder(getClusterConfigs(clientConfig, hostPort_1, hostPort_2)).build()); + + try (UnifiedJedis client = new UnifiedJedis(provider)) { + AbstractPipeline pipe = client.pipelined(); + pipe.set("pstr", "foobar"); + pipe.hset("phash", "foo", "bar"); + provider.incrementActiveMultiClusterIndex(); + pipe.sync(); + } + + assertEquals("foobar", jedis2.get("pstr")); + assertEquals("bar", jedis2.hget("phash", "foo")); + } + + @Test + public void transactionWithSwitch() { + MultiClusterPooledConnectionProvider provider = new MultiClusterPooledConnectionProvider( + new MultiClusterClientConfig.Builder(getClusterConfigs(clientConfig, hostPort_1, hostPort_2)).build()); + + try (UnifiedJedis client = new UnifiedJedis(provider)) { + AbstractTransaction tx = client.multi(); + tx.set("tstr", "foobar"); + tx.hset("thash", "foo", "bar"); + provider.incrementActiveMultiClusterIndex(); + assertEquals(Arrays.asList("OK", Long.valueOf(1L)), tx.exec()); + } + + assertEquals("foobar", jedis2.get("tstr")); + assertEquals("bar", jedis2.hget("thash", "foo")); + } + + @Test + public void commandFailover() { + int slidingWindowMinCalls = 10; + int slidingWindowSize = 10; + + MultiClusterClientConfig.Builder builder = new MultiClusterClientConfig.Builder( + getClusterConfigs(clientConfig, hostPort_1, hostPort_2)) + .circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) + .circuitBreakerSlidingWindowSize(slidingWindowSize); + + RedisFailoverReporter failoverReporter = new RedisFailoverReporter(); + MultiClusterPooledConnectionProvider cacheProvider = new MultiClusterPooledConnectionProvider(builder.build()); + cacheProvider.setClusterFailoverPostProcessor(failoverReporter); + + UnifiedJedis jedis = new UnifiedJedis(cacheProvider); + + String key = "hash-" + System.nanoTime(); + log.info("Starting calls to Redis"); + assertFalse(failoverReporter.failedOver); + for (int attempt = 0; attempt < 10; attempt++) { + try { + jedis.hset(key, "f1", "v1"); + } catch (JedisConnectionException jce) { + // + } + assertFalse(failoverReporter.failedOver); + } + + // should failover now + jedis.hset(key, "f1", "v1"); + assertTrue(failoverReporter.failedOver); + + assertEquals(Collections.singletonMap("f1", "v1"), jedis.hgetAll(key)); + jedis.flushAll(); + + jedis.close(); + } + + @Test + public void pipelineFailover() { + int slidingWindowMinCalls = 10; + int slidingWindowSize = 10; + + MultiClusterClientConfig.Builder builder = new MultiClusterClientConfig.Builder( + getClusterConfigs(clientConfig, hostPort_1, hostPort_2)) + .circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) + .circuitBreakerSlidingWindowSize(slidingWindowSize) + .fallbackExceptionList(Arrays.asList(JedisConnectionException.class)); + + RedisFailoverReporter failoverReporter = new RedisFailoverReporter(); + MultiClusterPooledConnectionProvider cacheProvider = new MultiClusterPooledConnectionProvider(builder.build()); + cacheProvider.setClusterFailoverPostProcessor(failoverReporter); + + UnifiedJedis jedis = new UnifiedJedis(cacheProvider); + + String key = "hash-" + System.nanoTime(); + log.info("Starting calls to Redis"); + assertFalse(failoverReporter.failedOver); + AbstractPipeline pipe = jedis.pipelined(); + assertFalse(failoverReporter.failedOver); + pipe.hset(key, "f1", "v1"); + assertFalse(failoverReporter.failedOver); + pipe.sync(); + assertTrue(failoverReporter.failedOver); + + assertEquals(Collections.singletonMap("f1", "v1"), jedis.hgetAll(key)); + jedis.flushAll(); + + jedis.close(); + } + + @Test + public void failoverFromAuthError() { + int slidingWindowMinCalls = 10; + int slidingWindowSize = 10; + + MultiClusterClientConfig.Builder builder = new MultiClusterClientConfig.Builder( + getClusterConfigs(clientConfig, hostPort_1_2, hostPort_2)) + .circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls) + .circuitBreakerSlidingWindowSize(slidingWindowSize) + .fallbackExceptionList(Arrays.asList(JedisAccessControlException.class)); + + RedisFailoverReporter failoverReporter = new RedisFailoverReporter(); + MultiClusterPooledConnectionProvider cacheProvider = new MultiClusterPooledConnectionProvider(builder.build()); + cacheProvider.setClusterFailoverPostProcessor(failoverReporter); + + UnifiedJedis jedis = new UnifiedJedis(cacheProvider); + + String key = "hash-" + System.nanoTime(); + log.info("Starting calls to Redis"); + assertFalse(failoverReporter.failedOver); + jedis.hset(key, "f1", "v1"); + assertTrue(failoverReporter.failedOver); + + assertEquals(Collections.singletonMap("f1", "v1"), jedis.hgetAll(key)); + jedis.flushAll(); + + jedis.close(); + } + + class RedisFailoverReporter implements Consumer { + + boolean failedOver = false; + + @Override + public void accept(String clusterName) { + log.info("Jedis fail over to cluster: " + clusterName); + failedOver = true; + } + } +} diff --git a/src/test/java/redis/clients/jedis/misc/ClientSetInfoConfigTest.java b/src/test/java/redis/clients/jedis/misc/ClientSetInfoConfigTest.java new file mode 100644 index 0000000000..8b85f70252 --- /dev/null +++ b/src/test/java/redis/clients/jedis/misc/ClientSetInfoConfigTest.java @@ -0,0 +1,26 @@ +package redis.clients.jedis.misc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import java.util.Arrays; +import org.junit.Test; + +import redis.clients.jedis.ClientSetInfoConfig; +import redis.clients.jedis.exceptions.JedisValidationException; + +public class ClientSetInfoConfigTest { + + @Test + public void replaceSpacesWithHyphens() { + assertEquals("Redis-Java-client", + ClientSetInfoConfig.withLibNameSuffix("Redis Java client").getLibNameSuffix()); + } + + @Test + public void errorForBraces() { + Arrays.asList('(', ')', '[', ']', '{', '}') + .forEach(brace -> assertThrows(JedisValidationException.class, + () -> ClientSetInfoConfig.withLibNameSuffix("" + brace))); + } +} diff --git a/src/test/java/redis/clients/jedis/modules/gears/GearsTest.java b/src/test/java/redis/clients/jedis/modules/gears/GearsTest.java new file mode 100644 index 0000000000..e4dc10a82d --- /dev/null +++ b/src/test/java/redis/clients/jedis/modules/gears/GearsTest.java @@ -0,0 +1,527 @@ +package redis.clients.jedis.modules.gears; + +import org.hamcrest.Matchers; +import org.junit.After; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import redis.clients.jedis.RedisProtocol; +import redis.clients.jedis.exceptions.JedisDataException; +import redis.clients.jedis.gears.TFunctionListParams; +import redis.clients.jedis.gears.TFunctionLoadParams; +import redis.clients.jedis.modules.RedisModuleCommandsTestBase; +import redis.clients.jedis.gears.resps.GearsLibraryInfo; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class GearsTest extends RedisModuleCommandsTestBase { + + private static final String BAD_FUNCTION = "All Your Base Are Belong to Us"; + + private static final String[] LIBRARIES_ARRAY = new String[]{ + "streamTriggers", "withFlags", "pingpong", "keyspaceTriggers", "hashitout", "withConfig"}; + + @BeforeClass + public static void prepare() { + RedisModuleCommandsTestBase.prepare(); + } + + @After + @Override + public void tearDown() throws Exception { + deleteFunctions(); // delete functions before closing connections + super.tearDown(); + } + + protected void deleteFunctions() { + List libraries = client.tFunctionList(); + libraries.stream().map(GearsLibraryInfo::getName).forEach(library -> client.tFunctionDelete(library)); + } + + @Test + public void testFunctionLoad() throws IOException { + client.tFunctionLoad(readLibrary("pingpong.js")); + + List libraries = client.tFunctionList(); + assertEquals(Collections.singletonList("pingpong"), + libraries.stream().map(GearsLibraryInfo::getName).collect(Collectors.toList())); + } + + @Test(expected = JedisDataException.class) + public void testFunctionLoadAlreadyLoadedFails() throws IOException { + client.tFunctionLoad(readLibrary("pingpong.js")); + client.tFunctionLoad(readLibrary("pingpong.js")); + } + + @Test + public void testFunctionLoadWithReplace() throws IOException { + client.tFunctionLoad(readLibrary("pingpong.js")); + client.tFunctionLoad(readLibrary("pingpong.js"), TFunctionLoadParams.loadParams().replace()); + + List libraries = client.tFunctionList(); + assertEquals(Collections.singletonList("pingpong"), + libraries.stream().map(GearsLibraryInfo::getName).collect(Collectors.toList())); + } + + @Test(expected = JedisDataException.class) + public void testBadFunctionLoad() { + client.tFunctionLoad(BAD_FUNCTION); + } + + private static void assertAllLibrariesNoCode(List libraryInfos) { + assertThat(libraryInfos, Matchers.hasSize(LIBRARIES_ARRAY.length)); + + List libraryNames = libraryInfos.stream().map(GearsLibraryInfo::getName).collect(Collectors.toList()); + assertThat(libraryNames, Matchers.containsInAnyOrder(LIBRARIES_ARRAY)); + + libraryInfos.stream().map(GearsLibraryInfo::getCode).forEach(Assert::assertNull); + } + + private static void assertAllLibrariesWithCode(List libraryInfos) { + assertThat(libraryInfos, Matchers.hasSize(LIBRARIES_ARRAY.length)); + + List libraryNames = libraryInfos.stream().map(GearsLibraryInfo::getName).collect(Collectors.toList()); + assertThat(libraryNames, Matchers.containsInAnyOrder(LIBRARIES_ARRAY)); + + libraryInfos.stream().map(GearsLibraryInfo::getCode).forEach(Assert::assertNotNull); + } + + @Test + public void tFunctionListAll() throws IOException { + loadAllLibraries(); + + List libraryInfos = client.tFunctionList(); + assertAllLibrariesNoCode(libraryInfos); + } + + @Test + public void testFunctionListNoCodeVerboseZero() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().verbose(0)); + assertAllLibrariesNoCode(libraryInfos); + + Map>> libraryConditions = initializeTestLibraryConditions(); + + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> "my_set".equalsIgnoreCase(func.getName()))); + libraryConditions.get("pingpong").add(lib -> lib.getFunctions().stream().anyMatch(func -> "playPingPong".equalsIgnoreCase(func.getName()))); + libraryConditions.get("keyspaceTriggers").add(lib -> lib.getKeyspaceTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("hashitout").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hashy".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withConfig").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hset".equalsIgnoreCase(func.getName()))); + + for (GearsLibraryInfo libraryInfo : libraryInfos) { + List> conditions = libraryConditions.get(libraryInfo.getName()); + if (conditions != null && !conditions.isEmpty()) { + conditions.forEach(c -> c.test(libraryInfo)); + } + } + } + + @Test + public void testFunctionListNoCodeVerboseOne() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().verbose(1)); + assertAllLibrariesNoCode(libraryInfos); + + Map>> libraryConditions = initializeTestLibraryConditions(); + + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "stream".equalsIgnoreCase(trigger.getPrefix()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> "my_set".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> func.getFlags().contains("raw-arguments"))); + libraryConditions.get("pingpong").add(lib -> lib.getFunctions().stream().anyMatch(func -> "playPingPong".equalsIgnoreCase(func.getName()))); + libraryConditions.get("keyspaceTriggers").add(lib -> lib.getKeyspaceTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("hashitout").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hashy".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withConfig").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hset".equalsIgnoreCase(func.getName()))); + + for (GearsLibraryInfo libraryInfo : libraryInfos) { + List> conditions = libraryConditions.get(libraryInfo.getName()); + if (conditions != null && !conditions.isEmpty()) { + conditions.forEach(c -> c.test(libraryInfo)); + } + } + } + + @Test + public void testFunctionListNoCodeVerboseTwo() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().verbose(2)); + assertAllLibrariesNoCode(libraryInfos); + + Map>> libraryConditions = initializeTestLibraryConditions(); + + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "stream".equalsIgnoreCase(trigger.getPrefix()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> "my_set".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> func.getFlags().contains("raw-arguments"))); + libraryConditions.get("pingpong").add(lib -> lib.getFunctions().stream().anyMatch(func -> "playPingPong".equalsIgnoreCase(func.getName()))); + libraryConditions.get("keyspaceTriggers").add(lib -> lib.getKeyspaceTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("hashitout").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hashy".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withConfig").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hset".equalsIgnoreCase(func.getName()))); + + for (GearsLibraryInfo libraryInfo : libraryInfos) { + List> conditions = libraryConditions.get(libraryInfo.getName()); + if (conditions != null && !conditions.isEmpty()) { + conditions.forEach(c -> c.test(libraryInfo)); + } + } + } + + @Test + public void testFunctionListNoCodeVerboseThree() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().verbose(3)); + assertAllLibrariesNoCode(libraryInfos); + + Map>> libraryConditions = initializeTestLibraryConditions(); + + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "stream".equalsIgnoreCase(trigger.getPrefix()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> "my_set".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> func.getFlags().contains("raw-arguments"))); + libraryConditions.get("pingpong").add(lib -> lib.getFunctions().stream().anyMatch(func -> "playPingPong".equalsIgnoreCase(func.getName()))); + libraryConditions.get("keyspaceTriggers").add(lib -> lib.getKeyspaceTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("hashitout").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hashy".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withConfig").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hset".equalsIgnoreCase(func.getName()))); + + for (GearsLibraryInfo libraryInfo : libraryInfos) { + List> conditions = libraryConditions.get(libraryInfo.getName()); + if (conditions != null && !conditions.isEmpty()) { + conditions.forEach(c -> c.test(libraryInfo)); + } + } + } + + @Test + public void testFunctionListWithCodeVerboseZero() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().withCode().verbose(0)); + assertAllLibrariesWithCode(libraryInfos); + + Map>> libraryConditions = initializeTestLibraryConditions(); + + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> "my_set".equalsIgnoreCase(func.getName()))); + libraryConditions.get("pingpong").add(lib -> lib.getFunctions().stream().anyMatch(func -> "playPingPong".equalsIgnoreCase(func.getName()))); + libraryConditions.get("keyspaceTriggers").add(lib -> lib.getKeyspaceTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("hashitout").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hashy".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withConfig").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hset".equalsIgnoreCase(func.getName()))); + + for (GearsLibraryInfo libraryInfo : libraryInfos) { + List> conditions = libraryConditions.get(libraryInfo.getName()); + if (conditions != null && !conditions.isEmpty()) { + conditions.forEach(c -> c.test(libraryInfo)); + } + } + } + + @Test + public void testFunctionListWithCodeVerboseOne() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().withCode().verbose(1)); + assertAllLibrariesWithCode(libraryInfos); + + Map>> libraryConditions = initializeTestLibraryConditions(); + + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "stream".equalsIgnoreCase(trigger.getPrefix()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> "my_set".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> func.getFlags().contains("raw-arguments"))); + libraryConditions.get("pingpong").add(lib -> lib.getFunctions().stream().anyMatch(func -> "playPingPong".equalsIgnoreCase(func.getName()))); + libraryConditions.get("keyspaceTriggers").add(lib -> lib.getKeyspaceTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("hashitout").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hashy".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withConfig").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hset".equalsIgnoreCase(func.getName()))); + + for (GearsLibraryInfo libraryInfo : libraryInfos) { + List> conditions = libraryConditions.get(libraryInfo.getName()); + if (conditions != null && !conditions.isEmpty()) { + conditions.forEach(c -> c.test(libraryInfo)); + } + } + } + + @Test + public void testFunctionListWithCodeVerboseTwo() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().withCode().verbose(2)); + assertAllLibrariesWithCode(libraryInfos); + + Map>> libraryConditions = initializeTestLibraryConditions(); + + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "stream".equalsIgnoreCase(trigger.getPrefix()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> "my_set".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> func.getFlags().contains("raw-arguments"))); + libraryConditions.get("pingpong").add(lib -> lib.getFunctions().stream().anyMatch(func -> "playPingPong".equalsIgnoreCase(func.getName()))); + libraryConditions.get("keyspaceTriggers").add(lib -> lib.getKeyspaceTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("hashitout").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hashy".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withConfig").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hset".equalsIgnoreCase(func.getName()))); + + for (GearsLibraryInfo libraryInfo : libraryInfos) { + List> conditions = libraryConditions.get(libraryInfo.getName()); + if (conditions != null && !conditions.isEmpty()) { + conditions.forEach(c -> c.test(libraryInfo)); + } + } + } + + @Test + public void testFunctionListWithCodeVerboseThree() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().withCode().verbose(3)); + assertAllLibrariesWithCode(libraryInfos); + + Map>> libraryConditions = initializeTestLibraryConditions(); + + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("streamTriggers").add(lib -> lib.getStreamTriggers().stream().anyMatch(trigger -> "stream".equalsIgnoreCase(trigger.getPrefix()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> "my_set".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withFlags").add(lib -> lib.getFunctions().stream().anyMatch(func -> func.getFlags().contains("raw-arguments"))); + libraryConditions.get("pingpong").add(lib -> lib.getFunctions().stream().anyMatch(func -> "playPingPong".equalsIgnoreCase(func.getName()))); + libraryConditions.get("keyspaceTriggers").add(lib -> lib.getKeyspaceTriggers().stream().anyMatch(trigger -> "consumer".equalsIgnoreCase(trigger.getName()))); + libraryConditions.get("hashitout").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hashy".equalsIgnoreCase(func.getName()))); + libraryConditions.get("withConfig").add(lib -> lib.getFunctions().stream().anyMatch(func -> "hset".equalsIgnoreCase(func.getName()))); + + for (GearsLibraryInfo libraryInfo : libraryInfos) { + List> conditions = libraryConditions.get(libraryInfo.getName()); + if (conditions != null && !conditions.isEmpty()) { + conditions.forEach(c -> c.test(libraryInfo)); + } + } + } + + @Test + public void testFunctionLibraryListNoCodeVerboseZero() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().library("pingpong")); + assertEquals(1, libraryInfos.size()); + assertEquals("pingpong", libraryInfos.get(0).getName()); + assertNull(libraryInfos.get(0).getFunctions().get(0).getDescription()); + assertNull(libraryInfos.get(0).getCode()); + } + + @Test + public void testFunctionLibraryListNoCodeVerboseOne() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().library("pingpong").verbose(1)); + + assertEquals(1, libraryInfos.size()); + assertEquals("pingpong", libraryInfos.get(0).getName()); + assertEquals("You PING, we PONG", libraryInfos.get(0).getFunctions().get(0).getDescription()); + assertNull(libraryInfos.get(0).getCode()); + } + + @Test + public void testFunctionLibraryListNoCodeVerboseTwo() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().library("pingpong").verbose(2)); + assertEquals(1, libraryInfos.size()); + assertEquals("pingpong", libraryInfos.get(0).getName()); + assertEquals("You PING, we PONG", libraryInfos.get(0).getFunctions().get(0).getDescription()); + assertNull(libraryInfos.get(0).getCode()); + } + + @Test + public void testFunctionLibraryListNoCodeVerboseThree() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().library("pingpong").verbose(3)); + assertEquals(1, libraryInfos.size()); + assertEquals("pingpong", libraryInfos.get(0).getName()); + assertEquals("You PING, we PONG", libraryInfos.get(0).getFunctions().get(0).getDescription()); + assertNull(libraryInfos.get(0).getCode()); + } + + @Test + public void testFunctionLibraryListWithCodeVerboseZero() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().library("pingpong").withCode()); + assertEquals(1, libraryInfos.size()); + assertEquals("pingpong", libraryInfos.get(0).getName()); + assertNull(libraryInfos.get(0).getFunctions().get(0).getDescription()); + assertNotNull(libraryInfos.get(0).getCode()); + } + + @Test + public void testFunctionLibraryListWithCodeVerboseOne() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().library("pingpong").withCode().verbose(1)); + assertEquals(1, libraryInfos.size()); + assertEquals("pingpong", libraryInfos.get(0).getName()); + assertEquals("You PING, we PONG", libraryInfos.get(0).getFunctions().get(0).getDescription()); + assertNotNull(libraryInfos.get(0).getCode()); + } + + @Test + public void testFunctionLibraryListWithCodeVerboseTwo() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().library("pingpong").withCode().verbose(2)); + assertEquals(1, libraryInfos.size()); + assertEquals("pingpong", libraryInfos.get(0).getName()); + assertEquals("You PING, we PONG", libraryInfos.get(0).getFunctions().get(0).getDescription()); + assertNotNull(libraryInfos.get(0).getCode()); + } + + @Test + public void testFunctionLibraryListWithCodeVerboseThree() throws IOException { + loadAllLibraries(); + List libraryInfos = client.tFunctionList(TFunctionListParams.listParams().library("pingpong").withCode().verbose(3)); + assertEquals(1, libraryInfos.size()); + assertEquals("pingpong", libraryInfos.get(0).getName()); + assertEquals("You PING, we PONG", libraryInfos.get(0).getFunctions().get(0).getDescription()); + assertNotNull(libraryInfos.get(0).getCode()); + } + + @Test + public void testLibraryDelete() throws IOException { + loadAllLibraries(); + assertEquals("OK", client.tFunctionDelete("pingpong")); + List libraryInfos = client.tFunctionList(); + assertEquals(LIBRARIES_ARRAY.length - 1, libraryInfos.size()); + } + + @Test + public void testLibraryCallStringResult() throws IOException { + loadAllLibraries(); + Object result = client.tFunctionCall("pingpong", "playPingPong", Collections.emptyList(), + Collections.emptyList()); + assertEquals(String.class, result.getClass()); + assertEquals("PONG", result); + } + + @Test + public void testLibraryCallSetValueResult() throws IOException { + loadAllLibraries(); + Object result = client.tFunctionCall("withFlags", "my_set", Collections.singletonList("MY_KEY"), + Collections.singletonList("MY_VALUE")); + assertEquals(String.class, result.getClass()); + assertEquals("OK", result); + assertEquals("MY_VALUE", client.get("MY_KEY")); + } + + @Test + public void testLibraryCallHashResult() throws IOException { + loadAllLibraries(); + Map payload = new HashMap<>(); + payload.put("C", "Dennis Ritchie"); + payload.put("Python", "Guido van Rossum"); + payload.put("C++", "Bjarne Stroustrup"); + payload.put("JavaScript", "Brendan Eich"); + payload.put("Java", "James Gosling"); + payload.put("Ruby", "Yukihiro Matsumoto"); + + client.hmset("hash1", payload); + + Object result = client.tFunctionCall("hashitout", "hashy", Collections.singletonList("hash1"), + Collections.emptyList()); + + final Map asMap; + + if (protocol != RedisProtocol.RESP3) { + final List asList = (List) result; + asMap = flatMapToMap(asList); + + } else { + asMap = (Map) result; + } + + payload.forEach((language, author) -> { + assertThat(asMap, Matchers.hasEntry(language, author)); + }); + assertThat(Long.parseLong(asMap.get("__last_updated__")), Matchers.greaterThan(0L)); + } + + @Test + public void testFunctionLoadWithConfig() throws IOException { + loadAllLibraries(); + List argsBefore = Arrays.asList("Dictionary1", "Pollito", "Chicken"); + client.tFunctionCall("withConfig", "hset", Collections.emptyList(), argsBefore); + + String config = "{\"last_modified_field_name\":\"changed_on\"}"; + client.tFunctionLoad(readLibrary("withConfig.js"), TFunctionLoadParams.loadParams().replace().config(config)); + + List argsAfter = Arrays.asList("Dictionary2", "Gallina", "Hen"); + Object result = client.tFunctionCall("withConfig", "hset", Collections.emptyList(), argsAfter); + assertEquals(2L, result); + + Map dict1 = client.hgetAll("Dictionary1"); + Map dict2 = client.hgetAll("Dictionary2"); + + assertTrue(dict1.containsKey("Pollito")); + assertTrue(dict1.containsKey("__last_modified__")); + assertFalse(dict1.containsKey("changed_on")); + + assertTrue(dict2.containsKey("Gallina")); + assertTrue(dict2.containsKey("changed_on")); + assertFalse(dict2.containsKey("__last_modified__")); + } + + @Test + public void testLibraryCallSetValueResultAsync() throws IOException { + loadAllLibraries(); + Object result = client.tFunctionCallAsync("withFlags", "my_set", Collections.singletonList("KEY_TWO"), + Collections.singletonList("KEY_TWO_VALUE")); + assertEquals(String.class, result.getClass()); + assertEquals("OK", result); + assertEquals("KEY_TWO_VALUE", client.get("KEY_TWO")); + } + + private static String readLibrary(String filename) throws IOException { + Path path = Paths.get("src/test/resources/functions/" + filename); + return String.join("\n", Files.readAllLines(path)); + } + + private void loadAllLibraries() throws IOException { + try (Stream walk = Files.walk(Paths.get("src/test/resources/functions/"))) { + List libs = walk + .filter(p -> !Files.isDirectory(p)) // + .map(Path::toString) // + .filter(f -> f.endsWith(".js")) // + .collect(Collectors.toList()); + + libs.forEach(lib -> { + String code; + try { + code = String.join("\n", Files.readAllLines(Paths.get(lib))); + } catch (IOException e) { + throw new RuntimeException(e); + } + client.tFunctionLoad(code, TFunctionLoadParams.loadParams().replace()); + }); + } + } + + private static Map>> initializeTestLibraryConditions() { + Map>> libraryConditions = new HashMap<>(); + libraryConditions.put("streamTriggers", new ArrayList<>()); + libraryConditions.put("withFlags", new ArrayList<>()); + libraryConditions.put("pingpong", new ArrayList<>()); + libraryConditions.put("keyspaceTriggers", new ArrayList<>()); + libraryConditions.put("hashitout", new ArrayList<>()); + libraryConditions.put("withConfig", new ArrayList<>()); + + return libraryConditions; + } + + private static Map flatMapToMap(List list) { + Map map = new HashMap(list.size() / 2); + for (int i = 0; i < list.size(); i += 2) { + map.put(list.get(i), list.get(i + 1)); + } + return map; + } +} diff --git a/src/test/java/redis/clients/jedis/modules/graph/GraphTransactionTest.java b/src/test/java/redis/clients/jedis/modules/graph/GraphTransactionTest.java index 2acf488d83..c63996e7b5 100644 --- a/src/test/java/redis/clients/jedis/modules/graph/GraphTransactionTest.java +++ b/src/test/java/redis/clients/jedis/modules/graph/GraphTransactionTest.java @@ -12,7 +12,7 @@ import org.junit.BeforeClass; import org.junit.Test; -import redis.clients.jedis.Transaction; +import redis.clients.jedis.AbstractTransaction; import redis.clients.jedis.graph.Header; import redis.clients.jedis.graph.Record; import redis.clients.jedis.graph.ResultSet; @@ -53,7 +53,7 @@ public static void prepare() { @Test public void testMultiExec() { // Transaction transaction = new Transaction(c); - Transaction transaction = client.multi(); + AbstractTransaction transaction = client.multi(); transaction.set("x", "1"); transaction.graphQuery("social", "CREATE (:Person {name:'a'})"); @@ -177,7 +177,7 @@ record = iterator.next(); @Test public void testMultiExecWithReadOnlyQueries() { // Transaction transaction = new Transaction(c); - Transaction transaction = client.multi(); + AbstractTransaction transaction = client.multi(); transaction.set("x", "1"); transaction.graphQuery("social", "CREATE (:Person {name:'a'})"); diff --git a/src/test/java/redis/clients/jedis/modules/json/RedisJsonV1Test.java b/src/test/java/redis/clients/jedis/modules/json/RedisJsonV1Test.java index cc9dcfdc05..5843b6e06a 100644 --- a/src/test/java/redis/clients/jedis/modules/json/RedisJsonV1Test.java +++ b/src/test/java/redis/clients/jedis/modules/json/RedisJsonV1Test.java @@ -14,8 +14,6 @@ import java.util.Collections; import java.util.List; -import org.hamcrest.MatcherAssert; -import org.hamcrest.Matchers; import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; @@ -34,7 +32,7 @@ public class RedisJsonV1Test extends RedisModuleCommandsTestBase { private final Gson gson = new Gson(); - private RedisJsonV1Commands jsonClient; + private RedisJsonV1Commands jsonV1; @BeforeClass public static void prepare() { @@ -46,7 +44,7 @@ public static void prepare() { @Override public void setUp() { super.setUp(); - this.jsonClient = super.client; + this.jsonV1 = super.client; } @Test @@ -54,143 +52,143 @@ public void basicSetGetShouldSucceed() { // naive set with a path // jsonClient.jsonSet("null", null, ROOT_PATH); - jsonClient.jsonSet("null", ROOT_PATH, (Object) null); - assertNull(jsonClient.jsonGet("null", String.class, ROOT_PATH)); + jsonV1.jsonSet("null", ROOT_PATH, (Object) null); + assertNull(jsonV1.jsonGet("null", String.class, ROOT_PATH)); // real scalar value and no path - jsonClient.jsonSet("str", ROOT_PATH, "strong"); - assertEquals("strong", jsonClient.jsonGet("str")); + jsonV1.jsonSet("str", ROOT_PATH, "strong"); + assertEquals("strong", jsonV1.jsonGet("str")); // a slightly more complex object IRLObject obj = new IRLObject(); - jsonClient.jsonSet("obj", ROOT_PATH, obj); + jsonV1.jsonSet("obj", ROOT_PATH, obj); Object expected = gson.fromJson(gson.toJson(obj), Object.class); - assertTrue(expected.equals(jsonClient.jsonGet("obj"))); + assertTrue(expected.equals(jsonV1.jsonGet("obj"))); // check an update Path p = Path.of(".str"); - jsonClient.jsonSet("obj", p, "strung"); - assertEquals("strung", jsonClient.jsonGet("obj", String.class, p)); + jsonV1.jsonSet("obj", p, "strung"); + assertEquals("strung", jsonV1.jsonGet("obj", String.class, p)); } @Test public void setExistingPathOnlyIfExistsShouldSucceed() { - jsonClient.jsonSet("obj", ROOT_PATH, new IRLObject()); + jsonV1.jsonSet("obj", ROOT_PATH, new IRLObject()); Path p = Path.of(".str"); - jsonClient.jsonSet("obj", p, "strangle", JsonSetParams.jsonSetParams().xx()); - assertEquals("strangle", jsonClient.jsonGet("obj", String.class, p)); + jsonV1.jsonSet("obj", p, "strangle", JsonSetParams.jsonSetParams().xx()); + assertEquals("strangle", jsonV1.jsonGet("obj", String.class, p)); } @Test public void setNonExistingOnlyIfNotExistsShouldSucceed() { - jsonClient.jsonSet("obj", ROOT_PATH, new IRLObject()); + jsonV1.jsonSet("obj", ROOT_PATH, new IRLObject()); Path p = Path.of(".none"); - jsonClient.jsonSet("obj", p, "strangle", JsonSetParams.jsonSetParams().nx()); - assertEquals("strangle", jsonClient.jsonGet("obj", String.class, p)); + jsonV1.jsonSet("obj", p, "strangle", JsonSetParams.jsonSetParams().nx()); + assertEquals("strangle", jsonV1.jsonGet("obj", String.class, p)); } @Test public void setWithoutAPathDefaultsToRootPath() { - jsonClient.jsonSet("obj1", ROOT_PATH, new IRLObject()); + jsonV1.jsonSet("obj1", ROOT_PATH, new IRLObject()); // jsonClient.jsonSet("obj1", "strangle", JsonSetParams.jsonSetParams().xx()); - jsonClient.jsonSetLegacy("obj1", (Object) "strangle", JsonSetParams.jsonSetParams().xx()); - assertEquals("strangle", jsonClient.jsonGet("obj1", String.class, ROOT_PATH)); + jsonV1.jsonSetLegacy("obj1", (Object) "strangle", JsonSetParams.jsonSetParams().xx()); + assertEquals("strangle", jsonV1.jsonGet("obj1", String.class, ROOT_PATH)); } @Test public void setExistingPathOnlyIfNotExistsShouldFail() { - jsonClient.jsonSet("obj", ROOT_PATH, new IRLObject()); + jsonV1.jsonSet("obj", ROOT_PATH, new IRLObject()); Path p = Path.of(".str"); - assertNull(jsonClient.jsonSet("obj", p, "strangle", JsonSetParams.jsonSetParams().nx())); + assertNull(jsonV1.jsonSet("obj", p, "strangle", JsonSetParams.jsonSetParams().nx())); } @Test public void setNonExistingPathOnlyIfExistsShouldFail() { - jsonClient.jsonSet("obj", ROOT_PATH, new IRLObject()); + jsonV1.jsonSet("obj", ROOT_PATH, new IRLObject()); Path p = Path.of(".none"); - assertNull(jsonClient.jsonSet("obj", p, "strangle", JsonSetParams.jsonSetParams().xx())); + assertNull(jsonV1.jsonSet("obj", p, "strangle", JsonSetParams.jsonSetParams().xx())); } @Test(expected = JedisDataException.class) public void setException() { // should error on non root path for new key - jsonClient.jsonSet("test", Path.of(".foo"), "bar"); + jsonV1.jsonSet("test", Path.of(".foo"), "bar"); } @Test public void getMultiplePathsShouldSucceed() { // check multiple paths IRLObject obj = new IRLObject(); - jsonClient.jsonSetLegacy("obj", obj); + jsonV1.jsonSetLegacy("obj", obj); Object expected = gson.fromJson(gson.toJson(obj), Object.class); - assertTrue(expected.equals(jsonClient.jsonGet("obj", Object.class, Path.of("bool"), Path.of("str")))); + assertTrue(expected.equals(jsonV1.jsonGet("obj", Object.class, Path.of("bool"), Path.of("str")))); } @Test public void toggle() { IRLObject obj = new IRLObject(); - jsonClient.jsonSetLegacy("obj", obj); + jsonV1.jsonSetLegacy("obj", obj); Path pbool = Path.of(".bool"); // check initial value - assertTrue(jsonClient.jsonGet("obj", Boolean.class, pbool)); + assertTrue(jsonV1.jsonGet("obj", Boolean.class, pbool)); // true -> false - jsonClient.jsonToggle("obj", pbool); - assertFalse(jsonClient.jsonGet("obj", Boolean.class, pbool)); + jsonV1.jsonToggle("obj", pbool); + assertFalse(jsonV1.jsonGet("obj", Boolean.class, pbool)); // false -> true - jsonClient.jsonToggle("obj", pbool); - assertTrue(jsonClient.jsonGet("obj", Boolean.class, pbool)); + jsonV1.jsonToggle("obj", pbool); + assertTrue(jsonV1.jsonGet("obj", Boolean.class, pbool)); // ignore non-boolean field Path pstr = Path.of(".str"); try { - jsonClient.jsonToggle("obj", pstr); + jsonV1.jsonToggle("obj", pstr); fail("String not a bool"); } catch (JedisDataException jde) { assertTrue(jde.getMessage().contains("not a bool")); } - assertEquals("string", jsonClient.jsonGet("obj", String.class, pstr)); + assertEquals("string", jsonV1.jsonGet("obj", String.class, pstr)); } @Test(expected = JedisDataException.class) public void getAbsent() { - jsonClient.jsonSet("test", ROOT_PATH, "foo"); - jsonClient.jsonGet("test", String.class, Path.of(".bar")); + jsonV1.jsonSet("test", ROOT_PATH, "foo"); + jsonV1.jsonGet("test", String.class, Path.of(".bar")); } @Test public void delValidShouldSucceed() { // check deletion of a single path - jsonClient.jsonSet("obj", ROOT_PATH, new IRLObject()); - assertEquals(1L, jsonClient.jsonDel("obj", Path.of(".str"))); + jsonV1.jsonSet("obj", ROOT_PATH, new IRLObject()); + assertEquals(1L, jsonV1.jsonDel("obj", Path.of(".str"))); assertTrue(client.exists("obj")); // check deletion root using default root -> key is removed - assertEquals(1L, jsonClient.jsonDel("obj")); + assertEquals(1L, jsonV1.jsonDel("obj")); assertFalse(client.exists("obj")); } @Test public void delNonExistingPathsAreIgnored() { - jsonClient.jsonSet("foobar", ROOT_PATH, new FooBarObject()); - assertEquals(0L, jsonClient.jsonDel("foobar", Path.of(".foo[1]"))); + jsonV1.jsonSet("foobar", ROOT_PATH, new FooBarObject()); + assertEquals(0L, jsonV1.jsonDel("foobar", Path.of(".foo[1]"))); } @Test public void typeChecksShouldSucceed() { - assertNull(jsonClient.jsonType("foobar")); - jsonClient.jsonSet("foobar", ROOT_PATH, new FooBarObject()); - assertSame(Object.class, jsonClient.jsonType("foobar")); - assertSame(Object.class, jsonClient.jsonType("foobar", ROOT_PATH)); - assertSame(String.class, jsonClient.jsonType("foobar", Path.of(".foo"))); - assertSame(int.class, jsonClient.jsonType("foobar", Path.of(".fooI"))); - assertSame(float.class, jsonClient.jsonType("foobar", Path.of(".fooF"))); - assertSame(List.class, jsonClient.jsonType("foobar", Path.of(".fooArr"))); - assertSame(boolean.class, jsonClient.jsonType("foobar", Path.of(".fooB"))); - assertNull(jsonClient.jsonType("foobar", Path.of(".fooErr"))); + assertNull(jsonV1.jsonType("foobar")); + jsonV1.jsonSet("foobar", ROOT_PATH, new FooBarObject()); + assertSame(Object.class, jsonV1.jsonType("foobar")); + assertSame(Object.class, jsonV1.jsonType("foobar", ROOT_PATH)); + assertSame(String.class, jsonV1.jsonType("foobar", Path.of(".foo"))); + assertSame(int.class, jsonV1.jsonType("foobar", Path.of(".fooI"))); + assertSame(float.class, jsonV1.jsonType("foobar", Path.of(".fooF"))); + assertSame(List.class, jsonV1.jsonType("foobar", Path.of(".fooArr"))); + assertSame(boolean.class, jsonV1.jsonType("foobar", Path.of(".fooB"))); + assertNull(jsonV1.jsonType("foobar", Path.of(".fooErr"))); } @Test @@ -199,7 +197,7 @@ public void testJsonMerge() { List childrens = new ArrayList<>(); childrens.add("Child 1"); Person person = new Person("John Doe", 25, "123 Main Street", "123-456-7890", childrens); - assertEquals("OK", jsonClient.jsonSet("test_merge", ROOT_PATH, person)); + assertEquals("OK", jsonV1.jsonSet("test_merge", ROOT_PATH, person)); // After 5 years: person.age = 30; @@ -207,9 +205,9 @@ public void testJsonMerge() { person.childrens.add("Child 3"); // merge the new data - assertEquals("OK", jsonClient.jsonMerge("test_merge", Path.of((".childrens")), person.childrens)); - assertEquals("OK", jsonClient.jsonMerge("test_merge", Path.of((".age")), person.age)); - assertEquals(person, jsonClient.jsonGet("test_merge", Person.class)); + assertEquals("OK", jsonV1.jsonMerge("test_merge", Path.of((".childrens")), person.childrens)); + assertEquals("OK", jsonV1.jsonMerge("test_merge", Path.of((".age")), person.age)); + assertEquals(person, jsonV1.jsonGet("test_merge", Person.class)); } @Test @@ -219,10 +217,10 @@ public void mgetWithPathWithAllKeysExist() { Qux qux1 = new Qux("quux1", "corge1", "garply1", baz1); Qux qux2 = new Qux("quux2", "corge2", "garply2", baz2); - jsonClient.jsonSetLegacy("qux1", qux1); - jsonClient.jsonSetLegacy("qux2", qux2); + jsonV1.jsonSetLegacy("qux1", qux1); + jsonV1.jsonSetLegacy("qux2", qux2); - List allBaz = jsonClient.jsonMGet(Path.of("baz"), Baz.class, "qux1", "qux2"); + List allBaz = jsonV1.jsonMGet(Path.of("baz"), Baz.class, "qux1", "qux2"); assertEquals(2, allBaz.size()); @@ -246,10 +244,10 @@ public void mgetAtRootPathWithMissingKeys() { Qux qux1 = new Qux("quux1", "corge1", "garply1", baz1); Qux qux2 = new Qux("quux2", "corge2", "garply2", baz2); - jsonClient.jsonSetLegacy("qux1", qux1); - jsonClient.jsonSetLegacy("qux2", qux2); + jsonV1.jsonSetLegacy("qux1", qux1); + jsonV1.jsonSetLegacy("qux2", qux2); - List allQux = jsonClient.jsonMGet(Qux.class, "qux1", "qux2", "qux3"); + List allQux = jsonV1.jsonMGet(Qux.class, "qux1", "qux2", "qux3"); assertEquals(3, allQux.size()); assertNull(allQux.get(2)); @@ -259,31 +257,31 @@ public void mgetAtRootPathWithMissingKeys() { @Test public void arrLen() { - jsonClient.jsonSet("foobar", ROOT_PATH, new FooBarObject()); - assertEquals(Long.valueOf(3), jsonClient.jsonArrLen("foobar", Path.of(".fooArr"))); + jsonV1.jsonSet("foobar", ROOT_PATH, new FooBarObject()); + assertEquals(Long.valueOf(3), jsonV1.jsonArrLen("foobar", Path.of(".fooArr"))); } @Test public void arrLenDefaultPath() { - assertNull(jsonClient.jsonArrLen("array")); - jsonClient.jsonSetLegacy("array", new int[]{1, 2, 3}); - assertEquals(Long.valueOf(3), jsonClient.jsonArrLen("array")); + assertNull(jsonV1.jsonArrLen("array")); + jsonV1.jsonSetLegacy("array", new int[]{1, 2, 3}); + assertEquals(Long.valueOf(3), jsonV1.jsonArrLen("array")); } @Test public void clearArray() { - jsonClient.jsonSet("foobar", ROOT_PATH, new FooBarObject()); + jsonV1.jsonSet("foobar", ROOT_PATH, new FooBarObject()); Path arrPath = Path.of(".fooArr"); - assertEquals(Long.valueOf(3), jsonClient.jsonArrLen("foobar", arrPath)); + assertEquals(Long.valueOf(3), jsonV1.jsonArrLen("foobar", arrPath)); - assertEquals(1L, jsonClient.jsonClear("foobar", arrPath)); - assertEquals(Long.valueOf(0), jsonClient.jsonArrLen("foobar", arrPath)); + assertEquals(1L, jsonV1.jsonClear("foobar", arrPath)); + assertEquals(Long.valueOf(0), jsonV1.jsonArrLen("foobar", arrPath)); // ignore non-array Path strPath = Path.of("foo"); - assertEquals(0L, jsonClient.jsonClear("foobar", strPath)); - assertEquals("bar", jsonClient.jsonGet("foobar", String.class, strPath)); + assertEquals(0L, jsonV1.jsonClear("foobar", strPath)); + assertEquals("bar", jsonV1.jsonGet("foobar", String.class, strPath)); } @Test @@ -291,12 +289,12 @@ public void clearObject() { Baz baz = new Baz("quuz", "grault", "waldo"); Qux qux = new Qux("quux", "corge", "garply", baz); - jsonClient.jsonSetLegacy("qux", qux); + jsonV1.jsonSetLegacy("qux", qux); Path objPath = Path.of("baz"); - assertEquals(baz, jsonClient.jsonGet("qux", Baz.class, objPath)); + assertEquals(baz, jsonV1.jsonGet("qux", Baz.class, objPath)); - assertEquals(1L, jsonClient.jsonClear("qux", objPath)); - assertEquals(new Baz(null, null, null), jsonClient.jsonGet("qux", Baz.class, objPath)); + assertEquals(1L, jsonV1.jsonClear("qux", objPath)); + assertEquals(new Baz(null, null, null), jsonV1.jsonGet("qux", Baz.class, objPath)); } @Test @@ -304,10 +302,10 @@ public void arrAppendSameType() { String json = "{ a: 'hello', b: [1, 2, 3], c: { d: ['ello'] }}"; JsonObject jsonObject = gson.fromJson(json, JsonObject.class); - jsonClient.jsonSet("test_arrappend", ROOT_PATH, jsonObject); - assertEquals(Long.valueOf(6), jsonClient.jsonArrAppend("test_arrappend", Path.of(".b"), 4, 5, 6)); + jsonV1.jsonSet("test_arrappend", ROOT_PATH, jsonObject); + assertEquals(Long.valueOf(6), jsonV1.jsonArrAppend("test_arrappend", Path.of(".b"), 4, 5, 6)); - Integer[] array = jsonClient.jsonGet("test_arrappend", Integer[].class, Path.of(".b")); + Integer[] array = jsonV1.jsonGet("test_arrappend", Integer[].class, Path.of(".b")); assertArrayEquals(new Integer[]{1, 2, 3, 4, 5, 6}, array); } @@ -316,10 +314,10 @@ public void arrAppendMultipleTypes() { String json = "{ a: 'hello', b: [1, 2, 3], c: { d: ['ello'] }}"; JsonObject jsonObject = gson.fromJson(json, JsonObject.class); - jsonClient.jsonSet("test_arrappend", ROOT_PATH, jsonObject); - assertEquals(Long.valueOf(6), jsonClient.jsonArrAppend("test_arrappend", Path.of(".b"), "foo", true, null)); + jsonV1.jsonSet("test_arrappend", ROOT_PATH, jsonObject); + assertEquals(Long.valueOf(6), jsonV1.jsonArrAppend("test_arrappend", Path.of(".b"), "foo", true, null)); - Object[] array = jsonClient.jsonGet("test_arrappend", Object[].class, Path.of(".b")); + Object[] array = jsonV1.jsonGet("test_arrappend", Object[].class, Path.of(".b")); // NOTE: GSon converts numeric types to the most accommodating type (Double) // when type information is not provided (as in the Object[] below) @@ -331,10 +329,10 @@ public void arrAppendMultipleTypesWithDeepPath() { String json = "{ a: 'hello', b: [1, 2, 3], c: { d: ['ello'] }}"; JsonObject jsonObject = gson.fromJson(json, JsonObject.class); - jsonClient.jsonSet("test_arrappend", ROOT_PATH, jsonObject); - assertEquals(Long.valueOf(4), jsonClient.jsonArrAppend("test_arrappend", Path.of(".c.d"), "foo", true, null)); + jsonV1.jsonSet("test_arrappend", ROOT_PATH, jsonObject); + assertEquals(Long.valueOf(4), jsonV1.jsonArrAppend("test_arrappend", Path.of(".c.d"), "foo", true, null)); - Object[] array = jsonClient.jsonGet("test_arrappend", Object[].class, Path.of(".c.d")); + Object[] array = jsonV1.jsonGet("test_arrappend", Object[].class, Path.of(".c.d")); assertArrayEquals(new Object[]{"ello", "foo", true, null}, array); } @@ -343,10 +341,10 @@ public void arrAppendAgaintsEmptyArray() { String json = "{ a: 'hello', b: [1, 2, 3], c: { d: [] }}"; JsonObject jsonObject = gson.fromJson(json, JsonObject.class); - jsonClient.jsonSet("test_arrappend", ROOT_PATH, jsonObject); - assertEquals(Long.valueOf(3), jsonClient.jsonArrAppend("test_arrappend", Path.of(".c.d"), "a", "b", "c")); + jsonV1.jsonSet("test_arrappend", ROOT_PATH, jsonObject); + assertEquals(Long.valueOf(3), jsonV1.jsonArrAppend("test_arrappend", Path.of(".c.d"), "a", "b", "c")); - String[] array = jsonClient.jsonGet("test_arrappend", String[].class, Path.of(".c.d")); + String[] array = jsonV1.jsonGet("test_arrappend", String[].class, Path.of(".c.d")); assertArrayEquals(new String[]{"a", "b", "c"}, array); } @@ -355,38 +353,38 @@ public void arrAppendPathIsNotArray() { String json = "{ a: 'hello', b: [1, 2, 3], c: { d: ['ello'] }}"; JsonObject jsonObject = gson.fromJson(json, JsonObject.class); - jsonClient.jsonSet("test_arrappend", ROOT_PATH, jsonObject); - jsonClient.jsonArrAppend("test_arrappend", Path.of(".a"), 1); + jsonV1.jsonSet("test_arrappend", ROOT_PATH, jsonObject); + jsonV1.jsonArrAppend("test_arrappend", Path.of(".a"), 1); } @Test(expected = JedisDataException.class) public void arrIndexAbsentKey() { - jsonClient.jsonArrIndex("quxquux", ROOT_PATH, gson.toJson(new Object())); + jsonV1.jsonArrIndex("quxquux", ROOT_PATH, gson.toJson(new Object())); } @Test public void arrIndexWithInts() { - jsonClient.jsonSet("quxquux", ROOT_PATH, new int[]{8, 6, 7, 5, 3, 0, 9}); - assertEquals(2L, jsonClient.jsonArrIndex("quxquux", ROOT_PATH, 7)); - assertEquals(-1L, jsonClient.jsonArrIndex("quxquux", ROOT_PATH, "7")); + jsonV1.jsonSet("quxquux", ROOT_PATH, new int[]{8, 6, 7, 5, 3, 0, 9}); + assertEquals(2L, jsonV1.jsonArrIndex("quxquux", ROOT_PATH, 7)); + assertEquals(-1L, jsonV1.jsonArrIndex("quxquux", ROOT_PATH, "7")); } @Test public void arrIndexWithStrings() { - jsonClient.jsonSet("quxquux", ROOT_PATH, new String[]{"8", "6", "7", "5", "3", "0", "9"}); - assertEquals(2L, jsonClient.jsonArrIndex("quxquux", ROOT_PATH, "7")); + jsonV1.jsonSet("quxquux", ROOT_PATH, new String[]{"8", "6", "7", "5", "3", "0", "9"}); + assertEquals(2L, jsonV1.jsonArrIndex("quxquux", ROOT_PATH, "7")); } @Test public void arrIndexWithStringsAndPath() { - jsonClient.jsonSet("foobar", ROOT_PATH, new FooBarObject()); - assertEquals(1L, jsonClient.jsonArrIndex("foobar", Path.of(".fooArr"), "b")); + jsonV1.jsonSet("foobar", ROOT_PATH, new FooBarObject()); + assertEquals(1L, jsonV1.jsonArrIndex("foobar", Path.of(".fooArr"), "b")); } @Test(expected = JedisDataException.class) public void arrIndexNonExistentPath() { - jsonClient.jsonSet("foobar", ROOT_PATH, new FooBarObject()); - assertEquals(1L, jsonClient.jsonArrIndex("foobar", Path.of(".barArr"), "x")); + jsonV1.jsonSet("foobar", ROOT_PATH, new FooBarObject()); + assertEquals(1L, jsonV1.jsonArrIndex("foobar", Path.of(".barArr"), "x")); } @Test @@ -394,10 +392,10 @@ public void arrInsert() { String json = "['hello', 'world', true, 1, 3, null, false]"; JsonArray jsonArray = gson.fromJson(json, JsonArray.class); - jsonClient.jsonSet("test_arrinsert", ROOT_PATH, jsonArray); - assertEquals(8L, jsonClient.jsonArrInsert("test_arrinsert", ROOT_PATH, 1, "foo")); + jsonV1.jsonSet("test_arrinsert", ROOT_PATH, jsonArray); + assertEquals(8L, jsonV1.jsonArrInsert("test_arrinsert", ROOT_PATH, 1, "foo")); - Object[] array = jsonClient.jsonGet("test_arrinsert", Object[].class, ROOT_PATH); + Object[] array = jsonV1.jsonGet("test_arrinsert", Object[].class, ROOT_PATH); // NOTE: GSon converts numeric types to the most accommodating type (Double) // when type information is not provided (as in the Object[] below) @@ -409,88 +407,88 @@ public void arrInsertWithNegativeIndex() { String json = "['hello', 'world', true, 1, 3, null, false]"; JsonArray jsonArray = gson.fromJson(json, JsonArray.class); - jsonClient.jsonSet("test_arrinsert", ROOT_PATH, jsonArray); - assertEquals(8L, jsonClient.jsonArrInsert("test_arrinsert", ROOT_PATH, -1, "foo")); + jsonV1.jsonSet("test_arrinsert", ROOT_PATH, jsonArray); + assertEquals(8L, jsonV1.jsonArrInsert("test_arrinsert", ROOT_PATH, -1, "foo")); - Object[] array = jsonClient.jsonGet("test_arrinsert", Object[].class, ROOT_PATH); + Object[] array = jsonV1.jsonGet("test_arrinsert", Object[].class, ROOT_PATH); assertArrayEquals(new Object[]{"hello", "world", true, 1.0, 3.0, null, "foo", false}, array); } @Test public void testArrayPop() { - jsonClient.jsonSet("arr", ROOT_PATH, new int[]{0, 1, 2, 3, 4}); - assertEquals(Long.valueOf(4), jsonClient.jsonArrPop("arr", Long.class, ROOT_PATH)); - assertEquals(Long.valueOf(3), jsonClient.jsonArrPop("arr", Long.class, ROOT_PATH, -1)); - assertEquals(Long.valueOf(2), jsonClient.jsonArrPop("arr", Long.class)); - assertEquals(Long.valueOf(0), jsonClient.jsonArrPop("arr", Long.class, ROOT_PATH, 0)); - assertEquals(Double.valueOf(1), jsonClient.jsonArrPop("arr")); + jsonV1.jsonSet("arr", ROOT_PATH, new int[]{0, 1, 2, 3, 4}); + assertEquals(Long.valueOf(4), jsonV1.jsonArrPop("arr", Long.class, ROOT_PATH)); + assertEquals(Long.valueOf(3), jsonV1.jsonArrPop("arr", Long.class, ROOT_PATH, -1)); + assertEquals(Long.valueOf(2), jsonV1.jsonArrPop("arr", Long.class)); + assertEquals(Long.valueOf(0), jsonV1.jsonArrPop("arr", Long.class, ROOT_PATH, 0)); + assertEquals(Double.valueOf(1), jsonV1.jsonArrPop("arr")); } @Test public void arrTrim() { - jsonClient.jsonSet("arr", ROOT_PATH, new int[]{0, 1, 2, 3, 4}); - assertEquals(Long.valueOf(3), jsonClient.jsonArrTrim("arr", ROOT_PATH, 1, 3)); - assertArrayEquals(new Integer[]{1, 2, 3}, jsonClient.jsonGet("arr", Integer[].class, ROOT_PATH)); + jsonV1.jsonSet("arr", ROOT_PATH, new int[]{0, 1, 2, 3, 4}); + assertEquals(Long.valueOf(3), jsonV1.jsonArrTrim("arr", ROOT_PATH, 1, 3)); + assertArrayEquals(new Integer[]{1, 2, 3}, jsonV1.jsonGet("arr", Integer[].class, ROOT_PATH)); } @Test public void strAppend() { - jsonClient.jsonSet("str", ROOT_PATH, "foo"); - assertEquals(6L, jsonClient.jsonStrAppend("str", ROOT_PATH, "bar")); - assertEquals("foobar", jsonClient.jsonGet("str", String.class, ROOT_PATH)); - assertEquals(8L, jsonClient.jsonStrAppend("str", "ed")); + jsonV1.jsonSet("str", ROOT_PATH, "foo"); + assertEquals(6L, jsonV1.jsonStrAppend("str", ROOT_PATH, "bar")); + assertEquals("foobar", jsonV1.jsonGet("str", String.class, ROOT_PATH)); + assertEquals(8L, jsonV1.jsonStrAppend("str", "ed")); // assertEquals("foobared", jsonClient.jsonGet("str", String.class)); - assertEquals("foobared", jsonClient.jsonGet("str")); + assertEquals("foobared", jsonV1.jsonGet("str")); } @Test public void strLen() { - assertNull(jsonClient.jsonStrLen("str")); - jsonClient.jsonSet("str", ROOT_PATH, "foo"); - assertEquals(Long.valueOf(3), jsonClient.jsonStrLen("str")); - assertEquals(Long.valueOf(3), jsonClient.jsonStrLen("str", ROOT_PATH)); + assertNull(jsonV1.jsonStrLen("str")); + jsonV1.jsonSet("str", ROOT_PATH, "foo"); + assertEquals(Long.valueOf(3), jsonV1.jsonStrLen("str")); + assertEquals(Long.valueOf(3), jsonV1.jsonStrLen("str", ROOT_PATH)); } @Test public void numIncrBy() { - jsonClient.jsonSetLegacy("doc", gson.fromJson("{a:3}", JsonObject.class)); - assertEquals(5d, jsonClient.jsonNumIncrBy("doc", Path.of(".a"), 2), 0d); + jsonV1.jsonSetLegacy("doc", gson.fromJson("{a:3}", JsonObject.class)); + assertEquals(5d, jsonV1.jsonNumIncrBy("doc", Path.of(".a"), 2), 0d); } @Test public void obj() { - assertNull(jsonClient.jsonObjLen("doc")); - assertNull(jsonClient.jsonObjKeys("doc")); - assertNull(jsonClient.jsonObjLen("doc", ROOT_PATH)); - assertNull(jsonClient.jsonObjKeys("doc", ROOT_PATH)); + assertNull(jsonV1.jsonObjLen("doc")); + assertNull(jsonV1.jsonObjKeys("doc")); + assertNull(jsonV1.jsonObjLen("doc", ROOT_PATH)); + assertNull(jsonV1.jsonObjKeys("doc", ROOT_PATH)); String json = "{\"a\":[3], \"nested\": {\"a\": {\"b\":2, \"c\": 1}}}"; - jsonClient.jsonSetWithPlainString("doc", ROOT_PATH, json); - assertEquals(Long.valueOf(2), jsonClient.jsonObjLen("doc")); - assertEquals(Arrays.asList("a", "nested"), jsonClient.jsonObjKeys("doc")); - assertEquals(Long.valueOf(2), jsonClient.jsonObjLen("doc", Path.of(".nested.a"))); - assertEquals(Arrays.asList("b", "c"), jsonClient.jsonObjKeys("doc", Path.of(".nested.a"))); + jsonV1.jsonSetWithPlainString("doc", ROOT_PATH, json); + assertEquals(Long.valueOf(2), jsonV1.jsonObjLen("doc")); + assertEquals(Arrays.asList("a", "nested"), jsonV1.jsonObjKeys("doc")); + assertEquals(Long.valueOf(2), jsonV1.jsonObjLen("doc", Path.of(".nested.a"))); + assertEquals(Arrays.asList("b", "c"), jsonV1.jsonObjKeys("doc", Path.of(".nested.a"))); } @Test public void debugMemory() { - assertEquals(0L, jsonClient.jsonDebugMemory("json")); - assertEquals(0L, jsonClient.jsonDebugMemory("json", ROOT_PATH)); + assertEquals(0L, jsonV1.jsonDebugMemory("json")); + assertEquals(0L, jsonV1.jsonDebugMemory("json", ROOT_PATH)); String json = "{ foo: 'bar', bar: { foo: 10 }}"; JsonObject jsonObject = gson.fromJson(json, JsonObject.class); - jsonClient.jsonSet("json", ROOT_PATH, jsonObject); + jsonV1.jsonSet("json", ROOT_PATH, jsonObject); // it is okay as long as any 'long' is returned - jsonClient.jsonDebugMemory("json"); - jsonClient.jsonDebugMemory("json", ROOT_PATH); - jsonClient.jsonDebugMemory("json", Path.of(".bar")); + jsonV1.jsonDebugMemory("json"); + jsonV1.jsonDebugMemory("json", ROOT_PATH); + jsonV1.jsonDebugMemory("json", Path.of(".bar")); } @Test public void plainString() { String json = "{\"foo\":\"bar\",\"bar\":{\"foo\":10}}"; - assertEquals("OK", jsonClient.jsonSetWithPlainString("plain", ROOT_PATH, json)); - assertEquals(json, jsonClient.jsonGetAsPlainString("plain", ROOT_PATH)); + assertEquals("OK", jsonV1.jsonSetWithPlainString("plain", ROOT_PATH, json)); + assertEquals(json, jsonV1.jsonGetAsPlainString("plain", ROOT_PATH)); } @Test @@ -500,9 +498,9 @@ public void testJsonGsonParser() { // setting the custom json gson parser client.setJsonObjectMapper(JsonObjectMapperTestUtil.getCustomGsonObjectMapper()); - jsonClient.jsonSet(person.getId(), ROOT_PATH, person); + jsonV1.jsonSet(person.getId(), ROOT_PATH, person); - String valueExpected = jsonClient.jsonGet(person.getId(), String.class, Path.of(".created")); + String valueExpected = jsonV1.jsonGet(person.getId(), String.class, Path.of(".created")); assertEquals(valueExpected, person.getCreated().toString()); } @@ -512,9 +510,9 @@ public void testDefaultJsonGsonParserStringsMustBeDifferent() { // using the default json gson parser which is automatically configured - jsonClient.jsonSet(tick.getId(), ROOT_PATH, tick); + jsonV1.jsonSet(tick.getId(), ROOT_PATH, tick); - Object valueExpected = jsonClient.jsonGet(tick.getId(), Path.of(".created")); + Object valueExpected = jsonV1.jsonGet(tick.getId(), Path.of(".created")); assertNotEquals(valueExpected, tick.getCreated().toString()); } @@ -525,9 +523,9 @@ public void testJsonJacksonParser() { // setting the custom json jackson parser client.setJsonObjectMapper(JsonObjectMapperTestUtil.getCustomJacksonObjectMapper()); - jsonClient.jsonSet(person.getId(), ROOT_PATH, person); + jsonV1.jsonSet(person.getId(), ROOT_PATH, person); - String valueExpected = jsonClient.jsonGet(person.getId(), String.class, Path.of(".created")); + String valueExpected = jsonV1.jsonGet(person.getId(), String.class, Path.of(".created")); assertEquals(valueExpected, person.getCreated().toString()); } } diff --git a/src/test/java/redis/clients/jedis/modules/json/RedisJsonV2Test.java b/src/test/java/redis/clients/jedis/modules/json/RedisJsonV2Test.java index bc9c34edb6..f36832da51 100644 --- a/src/test/java/redis/clients/jedis/modules/json/RedisJsonV2Test.java +++ b/src/test/java/redis/clients/jedis/modules/json/RedisJsonV2Test.java @@ -9,8 +9,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.hamcrest.MatcherAssert; -import org.hamcrest.Matchers; import org.json.JSONArray; import org.json.JSONObject; import org.junit.Assume; @@ -30,7 +28,7 @@ public class RedisJsonV2Test extends RedisModuleCommandsTestBase { private static final Gson gson = new Gson(); - private RedisJsonV2Commands jsonClient; + private RedisJsonV2Commands jsonV2; @BeforeClass public static void prepare() { @@ -41,7 +39,7 @@ public static void prepare() { @Override public void setUp() { super.setUp(); - this.jsonClient = super.client; + this.jsonV2 = super.client; } @Test @@ -49,23 +47,23 @@ public void basicSetGetShouldSucceed() { Assume.assumeFalse(RedisProtocolUtil.getRedisProtocol() == RedisProtocol.RESP3); // naive set with a path - jsonClient.jsonSetWithEscape("null", ROOT_PATH, (Object) null); - assertJsonArrayEquals(jsonArray((Object) null), jsonClient.jsonGet("null", ROOT_PATH)); + jsonV2.jsonSetWithEscape("null", ROOT_PATH, (Object) null); + assertJsonArrayEquals(jsonArray((Object) null), jsonV2.jsonGet("null", ROOT_PATH)); // real scalar value and no path - jsonClient.jsonSetWithEscape("str", "strong"); - assertEquals("strong", jsonClient.jsonGet("str")); + jsonV2.jsonSetWithEscape("str", "strong"); + assertEquals("strong", jsonV2.jsonGet("str")); // a slightly more complex object IRLObject obj = new IRLObject(); - jsonClient.jsonSetWithEscape("obj", obj); + jsonV2.jsonSetWithEscape("obj", obj); Object expected = gson.fromJson(gson.toJson(obj), Object.class); - assertTrue(expected.equals(jsonClient.jsonGet("obj"))); + assertTrue(expected.equals(jsonV2.jsonGet("obj"))); // check an update Path2 p = Path2.of(".str"); - jsonClient.jsonSet("obj", p, gson.toJson("strung")); - assertJsonArrayEquals(jsonArray("strung"), jsonClient.jsonGet("obj", p)); + jsonV2.jsonSet("obj", p, gson.toJson("strung")); + assertJsonArrayEquals(jsonArray("strung"), jsonV2.jsonGet("obj", p)); } @Test @@ -73,75 +71,75 @@ public void basicSetGetShouldSucceedResp3() { Assume.assumeTrue(RedisProtocolUtil.getRedisProtocol() == RedisProtocol.RESP3); // naive set with a path - jsonClient.jsonSetWithEscape("null", ROOT_PATH, (Object) null); - assertJsonArrayEquals(jsonArray((Object) null), jsonClient.jsonGet("null", ROOT_PATH)); + jsonV2.jsonSetWithEscape("null", ROOT_PATH, (Object) null); + assertJsonArrayEquals(jsonArray((Object) null), jsonV2.jsonGet("null", ROOT_PATH)); // real scalar value and no path - jsonClient.jsonSetWithEscape("str", "strong"); - assertJsonArrayEquals(jsonArray("strong"), jsonClient.jsonGet("str")); + jsonV2.jsonSetWithEscape("str", "strong"); + assertJsonArrayEquals(jsonArray("strong"), jsonV2.jsonGet("str")); // a slightly more complex object IRLObject obj = new IRLObject(); - jsonClient.jsonSetWithEscape("obj", obj); - assertJsonArrayEquals(jsonArray(new JSONObject(gson.toJson(obj))), jsonClient.jsonGet("obj")); + jsonV2.jsonSetWithEscape("obj", obj); + assertJsonArrayEquals(jsonArray(new JSONObject(gson.toJson(obj))), jsonV2.jsonGet("obj")); // check an update Path2 p = Path2.of(".str"); - jsonClient.jsonSet("obj", p, gson.toJson("strung")); - assertJsonArrayEquals(jsonArray("strung"), jsonClient.jsonGet("obj", p)); + jsonV2.jsonSet("obj", p, gson.toJson("strung")); + assertJsonArrayEquals(jsonArray("strung"), jsonV2.jsonGet("obj", p)); } @Test public void setExistingPathOnlyIfExistsShouldSucceed() { - jsonClient.jsonSetWithEscape("obj", new IRLObject()); + jsonV2.jsonSetWithEscape("obj", new IRLObject()); Path2 p = Path2.of(".str"); - jsonClient.jsonSetWithEscape("obj", p, "strangle", JsonSetParams.jsonSetParams().xx()); - assertJsonArrayEquals(jsonArray("strangle"), jsonClient.jsonGet("obj", p)); + jsonV2.jsonSetWithEscape("obj", p, "strangle", JsonSetParams.jsonSetParams().xx()); + assertJsonArrayEquals(jsonArray("strangle"), jsonV2.jsonGet("obj", p)); } @Test public void setNonExistingOnlyIfNotExistsShouldSucceed() { - jsonClient.jsonSet("obj", gson.toJson(new IRLObject())); + jsonV2.jsonSet("obj", gson.toJson(new IRLObject())); Path2 p = Path2.of(".none"); - jsonClient.jsonSet("obj", p, gson.toJson("strangle"), JsonSetParams.jsonSetParams().nx()); - assertJsonArrayEquals(jsonArray("strangle"), jsonClient.jsonGet("obj", p)); + jsonV2.jsonSet("obj", p, gson.toJson("strangle"), JsonSetParams.jsonSetParams().nx()); + assertJsonArrayEquals(jsonArray("strangle"), jsonV2.jsonGet("obj", p)); } @Test public void setWithoutAPathDefaultsToRootPath() { String objStr = gson.toJson(new IRLObject()); - jsonClient.jsonSet("obj1", new JSONObject(objStr)); + jsonV2.jsonSet("obj1", new JSONObject(objStr)); // jsonClient.jsonSet("obj1", "strangle", JsonSetParams.jsonSetParams().xx()); - jsonClient.jsonSetWithEscape("obj1", (Object) "strangle", JsonSetParams.jsonSetParams().xx()); - assertJsonArrayEquals(jsonArray("strangle"), jsonClient.jsonGet("obj1", ROOT_PATH)); + jsonV2.jsonSetWithEscape("obj1", (Object) "strangle", JsonSetParams.jsonSetParams().xx()); + assertJsonArrayEquals(jsonArray("strangle"), jsonV2.jsonGet("obj1", ROOT_PATH)); } @Test public void setExistingPathOnlyIfNotExistsShouldFail() { - jsonClient.jsonSetWithEscape("obj", new IRLObject()); + jsonV2.jsonSetWithEscape("obj", new IRLObject()); Path2 p = Path2.of(".str"); - assertNull(jsonClient.jsonSetWithEscape("obj", p, "strangle", JsonSetParams.jsonSetParams().nx())); + assertNull(jsonV2.jsonSetWithEscape("obj", p, "strangle", JsonSetParams.jsonSetParams().nx())); } @Test public void setNonExistingPathOnlyIfExistsShouldFail() { - jsonClient.jsonSetWithEscape("obj", new IRLObject()); + jsonV2.jsonSetWithEscape("obj", new IRLObject()); Path2 p = Path2.of(".none"); - assertNull(jsonClient.jsonSetWithEscape("obj", p, "strangle", JsonSetParams.jsonSetParams().xx())); + assertNull(jsonV2.jsonSetWithEscape("obj", p, "strangle", JsonSetParams.jsonSetParams().xx())); } @Test(expected = JedisDataException.class) public void setException() { // should error on non root path for new key - jsonClient.jsonSet("test", Path2.of(".foo"), "bar"); + jsonV2.jsonSet("test", Path2.of(".foo"), "bar"); } @Test public void getMultiplePathsShouldSucceed() { // check multiple paths IRLObject obj = new IRLObject(); - jsonClient.jsonSetWithEscape("obj", obj); - JSONObject result = (JSONObject) jsonClient.jsonGet("obj", Path2.of("bool"), Path2.of("str")); + jsonV2.jsonSetWithEscape("obj", obj); + JSONObject result = (JSONObject) jsonV2.jsonGet("obj", Path2.of("bool"), Path2.of("str")); assertJsonArrayEquals(jsonArray(true), result.get("$.bool")); assertJsonArrayEquals(jsonArray("string"), result.get("$.str")); } @@ -153,90 +151,90 @@ public void getMultiLevels() { JSONObject inner = new JSONObject(); inner.put("foo", "Jane"); obj.put("bar", inner); - jsonClient.jsonSet("multi", obj); - assertJsonArrayEquals(jsonArray("John", "Jane"), jsonClient.jsonGet("multi", new Path2("..foo"))); + jsonV2.jsonSet("multi", obj); + assertJsonArrayEquals(jsonArray("John", "Jane"), jsonV2.jsonGet("multi", new Path2("..foo"))); } @Test public void toggle() { IRLObject obj = new IRLObject(); - jsonClient.jsonSetWithEscape("obj", obj); + jsonV2.jsonSetWithEscape("obj", obj); Path2 pbool = Path2.of(".bool"); // check initial value - assertJsonArrayEquals(jsonArray(true), jsonClient.jsonGet("obj", pbool)); + assertJsonArrayEquals(jsonArray(true), jsonV2.jsonGet("obj", pbool)); // true -> false - jsonClient.jsonToggle("obj", pbool); - assertJsonArrayEquals(jsonArray(false), jsonClient.jsonGet("obj", pbool)); + jsonV2.jsonToggle("obj", pbool); + assertJsonArrayEquals(jsonArray(false), jsonV2.jsonGet("obj", pbool)); // false -> true - jsonClient.jsonToggle("obj", pbool); - assertJsonArrayEquals(jsonArray(true), jsonClient.jsonGet("obj", pbool)); + jsonV2.jsonToggle("obj", pbool); + assertJsonArrayEquals(jsonArray(true), jsonV2.jsonGet("obj", pbool)); // ignore non-boolean field Path2 pstr = Path2.of(".str"); - assertEquals(singletonList(null), jsonClient.jsonToggle("obj", pstr)); - assertJsonArrayEquals(jsonArray("string"), jsonClient.jsonGet("obj", pstr)); + assertEquals(singletonList(null), jsonV2.jsonToggle("obj", pstr)); + assertJsonArrayEquals(jsonArray("string"), jsonV2.jsonGet("obj", pstr)); } @Test public void getAbsent() { - jsonClient.jsonSetWithEscape("test", ROOT_PATH, "foo"); - assertJsonArrayEquals(jsonArray(), jsonClient.jsonGet("test", Path2.of(".bar"))); + jsonV2.jsonSetWithEscape("test", ROOT_PATH, "foo"); + assertJsonArrayEquals(jsonArray(), jsonV2.jsonGet("test", Path2.of(".bar"))); } @Test public void delValidShouldSucceed() { // check deletion of a single path - jsonClient.jsonSetWithEscape("obj", ROOT_PATH, new IRLObject()); - assertEquals(1L, jsonClient.jsonDel("obj", Path2.of(".str"))); + jsonV2.jsonSetWithEscape("obj", ROOT_PATH, new IRLObject()); + assertEquals(1L, jsonV2.jsonDel("obj", Path2.of(".str"))); assertTrue(client.exists("obj")); // check deletion root using default root -> key is removed - assertEquals(1L, jsonClient.jsonDel("obj")); + assertEquals(1L, jsonV2.jsonDel("obj")); assertFalse(client.exists("obj")); } @Test public void delNonExistingPathsAreIgnored() { - jsonClient.jsonSetWithEscape("foobar", ROOT_PATH, new FooBarObject()); - assertEquals(0L, jsonClient.jsonDel("foobar", Path2.of(".foo[1]"))); + jsonV2.jsonSetWithEscape("foobar", ROOT_PATH, new FooBarObject()); + assertEquals(0L, jsonV2.jsonDel("foobar", Path2.of(".foo[1]"))); } @Test public void typeChecksShouldSucceed() { - jsonClient.jsonSet("foobar", ROOT_PATH, new JSONObject(gson.toJson(new FooBarObject()))); - assertEquals(singletonList(Object.class), jsonClient.jsonType("foobar", ROOT_PATH)); - assertEquals(singletonList(String.class), jsonClient.jsonType("foobar", Path2.of(".foo"))); - assertEquals(singletonList(int.class), jsonClient.jsonType("foobar", Path2.of(".fooI"))); - assertEquals(singletonList(float.class), jsonClient.jsonType("foobar", Path2.of(".fooF"))); - assertEquals(singletonList(List.class), jsonClient.jsonType("foobar", Path2.of(".fooArr"))); - assertEquals(singletonList(boolean.class), jsonClient.jsonType("foobar", Path2.of(".fooB"))); - assertEquals(Collections.emptyList(), jsonClient.jsonType("foobar", Path2.of(".fooErr"))); + jsonV2.jsonSet("foobar", ROOT_PATH, new JSONObject(gson.toJson(new FooBarObject()))); + assertEquals(singletonList(Object.class), jsonV2.jsonType("foobar", ROOT_PATH)); + assertEquals(singletonList(String.class), jsonV2.jsonType("foobar", Path2.of(".foo"))); + assertEquals(singletonList(int.class), jsonV2.jsonType("foobar", Path2.of(".fooI"))); + assertEquals(singletonList(float.class), jsonV2.jsonType("foobar", Path2.of(".fooF"))); + assertEquals(singletonList(List.class), jsonV2.jsonType("foobar", Path2.of(".fooArr"))); + assertEquals(singletonList(boolean.class), jsonV2.jsonType("foobar", Path2.of(".fooB"))); + assertEquals(Collections.emptyList(), jsonV2.jsonType("foobar", Path2.of(".fooErr"))); } @Test public void testJsonMerge() { // Test with root path JSONObject json = new JSONObject("{\"person\":{\"name\":\"John Doe\",\"age\":25,\"address\":{\"home\":\"123 Main Street\"},\"phone\":\"123-456-7890\"}}"); - assertEquals("OK", jsonClient.jsonSet("test_merge", json)); + assertEquals("OK", jsonV2.jsonSet("test_merge", json)); json = new JSONObject("{\"person\":{\"name\":\"John Doe\",\"age\":30,\"address\":{\"home\":\"123 Main Street\"},\"phone\":\"123-456-7890\"}}"); - assertEquals("OK", jsonClient.jsonMerge("test_merge", Path2.of("$"), "{\"person\":{\"age\":30}}")); + assertEquals("OK", jsonV2.jsonMerge("test_merge", Path2.of("$"), "{\"person\":{\"age\":30}}")); - assertJsonArrayEquals(jsonArray(json), jsonClient.jsonGet("test_merge", Path2.of("$"))); + assertJsonArrayEquals(jsonArray(json), jsonV2.jsonGet("test_merge", Path2.of("$"))); // Test with root path path $.a.b - assertEquals("OK", jsonClient.jsonMerge("test_merge", Path2.of("$.person.address"), "{\"work\":\"Redis office\"}")); + assertEquals("OK", jsonV2.jsonMerge("test_merge", Path2.of("$.person.address"), "{\"work\":\"Redis office\"}")); json = new JSONObject("{\"person\":{\"name\":\"John Doe\",\"age\":30,\"address\":{\"home\":\"123 Main Street\",\"work\":\"Redis office\"},\"phone\":\"123-456-7890\"}}"); - assertJsonArrayEquals(jsonArray(json), jsonClient.jsonGet("test_merge", Path2.of("$"))); + assertJsonArrayEquals(jsonArray(json), jsonV2.jsonGet("test_merge", Path2.of("$"))); // Test with null value to delete a value - assertEquals("OK", jsonClient.jsonMerge("test_merge", Path2.of("$.person"), "{\"age\":null}")); + assertEquals("OK", jsonV2.jsonMerge("test_merge", Path2.of("$.person"), "{\"age\":null}")); json = new JSONObject("{\"person\":{\"name\":\"John Doe\",\"address\":{\"home\":\"123 Main Street\",\"work\":\"Redis office\"},\"phone\":\"123-456-7890\"}}"); - assertJsonArrayEquals(jsonArray(json), jsonClient.jsonGet("test_merge", Path2.of("$"))); + assertJsonArrayEquals(jsonArray(json), jsonV2.jsonGet("test_merge", Path2.of("$"))); // cleanup assertEquals(1L, client.del("test_merge")); @@ -247,25 +245,25 @@ public void testJsonMergeArray() { // Test merge on an array JSONObject json = new JSONObject("{\"a\":{\"b\":{\"c\":[\"d\",\"e\"]}}}"); - assertEquals("OK", jsonClient.jsonSet("test_merge_array", Path2.of("$"), json)); - assertEquals("OK", jsonClient.jsonMerge("test_merge_array", Path2.of("$.a.b.c"), "[\"f\"]")); + assertEquals("OK", jsonV2.jsonSet("test_merge_array", Path2.of("$"), json)); + assertEquals("OK", jsonV2.jsonMerge("test_merge_array", Path2.of("$.a.b.c"), "[\"f\"]")); json = new JSONObject("{\"a\":{\"b\":{\"c\":[\"f\"]}}}"); - assertJsonArrayEquals(jsonArray(json), jsonClient.jsonGet("test_merge_array", Path2.of("$"))); + assertJsonArrayEquals(jsonArray(json), jsonV2.jsonGet("test_merge_array", Path2.of("$"))); // assertEquals("{{a={b={c=[f]}}}", jsonClient.jsonGet("test_merge_array", Path2.of("$"))); // Test merge an array on a value - assertEquals("OK", jsonClient.jsonSet("test_merge_array", Path2.of("$"), "{\"a\":{\"b\":{\"c\":\"d\"}}}")); - assertEquals("OK", jsonClient.jsonMerge("test_merge_array", Path2.of("$.a.b.c"), "[\"f\"]")); + assertEquals("OK", jsonV2.jsonSet("test_merge_array", Path2.of("$"), "{\"a\":{\"b\":{\"c\":\"d\"}}}")); + assertEquals("OK", jsonV2.jsonMerge("test_merge_array", Path2.of("$.a.b.c"), "[\"f\"]")); json = new JSONObject("{\"a\":{\"b\":{\"c\":[\"f\"]}}}"); - assertJsonArrayEquals(jsonArray(json), jsonClient.jsonGet("test_merge_array", Path2.of("$"))); + assertJsonArrayEquals(jsonArray(json), jsonV2.jsonGet("test_merge_array", Path2.of("$"))); // Test with null value to delete an array value - assertEquals("OK", jsonClient.jsonSet("test_merge_array", Path2.of("$"), "{\"a\":{\"b\":{\"c\":[\"d\",\"e\"]}}}")); - assertEquals("OK", jsonClient.jsonMerge("test_merge_array", Path2.of("$.a.b"), "{\"c\":null}")); + assertEquals("OK", jsonV2.jsonSet("test_merge_array", Path2.of("$"), "{\"a\":{\"b\":{\"c\":[\"d\",\"e\"]}}}")); + assertEquals("OK", jsonV2.jsonMerge("test_merge_array", Path2.of("$.a.b"), "{\"c\":null}")); json = new JSONObject("{\"a\":{\"b\":{}}}"); - assertJsonArrayEquals(jsonArray(json), jsonClient.jsonGet("test_merge_array", Path2.of("$"))); + assertJsonArrayEquals(jsonArray(json), jsonV2.jsonGet("test_merge_array", Path2.of("$"))); } @Test @@ -275,10 +273,10 @@ public void mgetWithPathWithAllKeysExist() { Qux qux1 = new Qux("quux1", "corge1", "garply1", baz1); Qux qux2 = new Qux("quux2", "corge2", "garply2", baz2); - jsonClient.jsonSet("qux1", new JSONObject(gson.toJson(qux1))); - jsonClient.jsonSet("qux2", new JSONObject(gson.toJson(qux2))); + jsonV2.jsonSet("qux1", new JSONObject(gson.toJson(qux1))); + jsonV2.jsonSet("qux2", new JSONObject(gson.toJson(qux2))); - List list = jsonClient.jsonMGet(Path2.of("baz"), "qux1", "qux2"); + List list = jsonV2.jsonMGet(Path2.of("baz"), "qux1", "qux2"); assertEquals(2, list.size()); assertJsonArrayEquals(jsonArray(new JSONObject(gson.toJson(baz1))), list.get(0)); assertJsonArrayEquals(jsonArray(new JSONObject(gson.toJson(baz2))), list.get(1)); @@ -291,10 +289,10 @@ public void mgetAtRootPathWithMissingKeys() { Qux qux1 = new Qux("quux1", "corge1", "garply1", baz1); Qux qux2 = new Qux("quux2", "corge2", "garply2", baz2); - jsonClient.jsonSetWithEscape("qux1", qux1); - jsonClient.jsonSetWithEscape("qux2", qux2); + jsonV2.jsonSetWithEscape("qux1", qux1); + jsonV2.jsonSetWithEscape("qux2", qux2); - List list = jsonClient.jsonMGet("qux1", "qux2", "qux3"); + List list = jsonV2.jsonMGet("qux1", "qux2", "qux3"); assertEquals(3, list.size()); assertNull(list.get(2)); @@ -304,24 +302,24 @@ public void mgetAtRootPathWithMissingKeys() { @Test public void arrLen() { - jsonClient.jsonSet("arr", ROOT_PATH, new JSONArray(new int[]{0, 1, 2, 3, 4})); - assertEquals(singletonList(5L), jsonClient.jsonArrLen("arr", ROOT_PATH)); + jsonV2.jsonSet("arr", ROOT_PATH, new JSONArray(new int[]{0, 1, 2, 3, 4})); + assertEquals(singletonList(5L), jsonV2.jsonArrLen("arr", ROOT_PATH)); } @Test public void clearArray() { - jsonClient.jsonSet("foobar", ROOT_PATH, gson.toJson(new FooBarObject())); + jsonV2.jsonSet("foobar", ROOT_PATH, gson.toJson(new FooBarObject())); Path2 arrPath = Path2.of(".fooArr"); - assertEquals(singletonList(3L), jsonClient.jsonArrLen("foobar", arrPath)); + assertEquals(singletonList(3L), jsonV2.jsonArrLen("foobar", arrPath)); - assertEquals(1L, jsonClient.jsonClear("foobar", arrPath)); - assertEquals(singletonList(0L), jsonClient.jsonArrLen("foobar", arrPath)); + assertEquals(1L, jsonV2.jsonClear("foobar", arrPath)); + assertEquals(singletonList(0L), jsonV2.jsonArrLen("foobar", arrPath)); // ignore non-array Path2 strPath = Path2.of(".foo"); - assertEquals(0L, jsonClient.jsonClear("foobar", strPath)); - assertJsonArrayEquals(jsonArray("bar"), jsonClient.jsonGet("foobar", strPath)); + assertEquals(0L, jsonV2.jsonClear("foobar", strPath)); + assertJsonArrayEquals(jsonArray("bar"), jsonV2.jsonGet("foobar", strPath)); } @Test @@ -329,22 +327,22 @@ public void clearObject() { Baz baz = new Baz("quuz", "grault", "waldo"); Qux qux = new Qux("quux", "corge", "garply", baz); - jsonClient.jsonSet("qux", gson.toJson(qux)); + jsonV2.jsonSet("qux", gson.toJson(qux)); Path2 objPath = Path2.of(".baz"); // assertEquals(baz, jsonClient.jsonGet("qux", objPath)); - assertEquals(1L, jsonClient.jsonClear("qux", objPath)); + assertEquals(1L, jsonV2.jsonClear("qux", objPath)); // assertEquals(new Baz(null, null, null), jsonClient.jsonGet("qux", objPath)); - assertJsonArrayEquals(jsonArray(new JSONObject()), jsonClient.jsonGet("qux", objPath)); + assertJsonArrayEquals(jsonArray(new JSONObject()), jsonV2.jsonGet("qux", objPath)); } @Test public void arrAppendSameType() { String json = "{ a: 'hello', b: [1, 2, 3], c: { d: ['ello'] }}"; - jsonClient.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); - assertEquals(singletonList(6L), jsonClient.jsonArrAppend("test_arrappend", Path2.of(".b"), 4, 5, 6)); + jsonV2.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); + assertEquals(singletonList(6L), jsonV2.jsonArrAppend("test_arrappend", Path2.of(".b"), 4, 5, 6)); - assertJsonArrayEquals(jsonArray(jsonArray(1, 2, 3, 4, 5, 6)), jsonClient.jsonGet("test_arrappend", Path2.of(".b"))); + assertJsonArrayEquals(jsonArray(jsonArray(1, 2, 3, 4, 5, 6)), jsonV2.jsonGet("test_arrappend", Path2.of(".b"))); } @Test @@ -353,158 +351,158 @@ public void arrAppendMultipleTypes() { Object trueObject = gson.toJson(true); Object nullObject = gson.toJson(null); String json = "{ a: 'hello', b: [1, 2, 3], c: { d: ['ello'] }}"; - jsonClient.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); - assertEquals(singletonList(6L), jsonClient.jsonArrAppend("test_arrappend", Path2.of(".b"), fooObject, trueObject, nullObject)); + jsonV2.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); + assertEquals(singletonList(6L), jsonV2.jsonArrAppend("test_arrappend", Path2.of(".b"), fooObject, trueObject, nullObject)); - assertJsonArrayEquals(jsonArray(jsonArray(1, 2, 3, "foo", true, null)), jsonClient.jsonGet("test_arrappend", Path2.of(".b"))); + assertJsonArrayEquals(jsonArray(jsonArray(1, 2, 3, "foo", true, null)), jsonV2.jsonGet("test_arrappend", Path2.of(".b"))); } @Test public void arrAppendMultipleTypesWithDeepPath() { String json = "{ a: 'hello', b: [1, 2, 3], c: { d: ['ello'] }}"; - jsonClient.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); - assertEquals(singletonList(4L), jsonClient.jsonArrAppendWithEscape("test_arrappend", Path2.of(".c.d"), "foo", true, null)); + jsonV2.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); + assertEquals(singletonList(4L), jsonV2.jsonArrAppendWithEscape("test_arrappend", Path2.of(".c.d"), "foo", true, null)); - assertJsonArrayEquals(jsonArray(jsonArray("ello", "foo", true, null)), jsonClient.jsonGet("test_arrappend", Path2.of(".c.d"))); + assertJsonArrayEquals(jsonArray(jsonArray("ello", "foo", true, null)), jsonV2.jsonGet("test_arrappend", Path2.of(".c.d"))); } @Test public void arrAppendAgaintsEmptyArray() { String json = "{ a: 'hello', b: [1, 2, 3], c: { d: [] }}"; - jsonClient.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); - assertEquals(singletonList(3L), jsonClient.jsonArrAppendWithEscape("test_arrappend", Path2.of(".c.d"), "a", "b", "c")); + jsonV2.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); + assertEquals(singletonList(3L), jsonV2.jsonArrAppendWithEscape("test_arrappend", Path2.of(".c.d"), "a", "b", "c")); - assertJsonArrayEquals(jsonArray(jsonArray("a", "b", "c")), jsonClient.jsonGet("test_arrappend", Path2.of(".c.d"))); + assertJsonArrayEquals(jsonArray(jsonArray("a", "b", "c")), jsonV2.jsonGet("test_arrappend", Path2.of(".c.d"))); } @Test public void arrAppendPathIsNotArray() { String json = "{ a: 'hello', b: [1, 2, 3], c: { d: ['ello'] }}"; - jsonClient.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); - assertEquals(singletonList(null), jsonClient.jsonArrAppend("test_arrappend", Path2.of(".a"), 1)); - assertEquals(singletonList(null), jsonClient.jsonArrAppend("test_arrappend", Path2.of(".a"), gson.toJson(1))); - assertEquals(singletonList(null), jsonClient.jsonArrAppendWithEscape("test_arrappend", Path2.of(".a"), 1)); + jsonV2.jsonSet("test_arrappend", ROOT_PATH, new JSONObject(json)); + assertEquals(singletonList(null), jsonV2.jsonArrAppend("test_arrappend", Path2.of(".a"), 1)); + assertEquals(singletonList(null), jsonV2.jsonArrAppend("test_arrappend", Path2.of(".a"), gson.toJson(1))); + assertEquals(singletonList(null), jsonV2.jsonArrAppendWithEscape("test_arrappend", Path2.of(".a"), 1)); } @Test(expected = JedisDataException.class) public void arrIndexAbsentKey() { - jsonClient.jsonArrIndexWithEscape("quxquux", ROOT_PATH, new JSONObject()); + jsonV2.jsonArrIndexWithEscape("quxquux", ROOT_PATH, new JSONObject()); } @Test public void arrIndexWithInts() { - jsonClient.jsonSetWithEscape("quxquux", ROOT_PATH, new int[]{8, 6, 7, 5, 3, 0, 9}); - assertEquals(singletonList(2L), jsonClient.jsonArrIndexWithEscape("quxquux", ROOT_PATH, 7)); - assertEquals(singletonList(-1L), jsonClient.jsonArrIndexWithEscape("quxquux", ROOT_PATH, "7")); + jsonV2.jsonSetWithEscape("quxquux", ROOT_PATH, new int[]{8, 6, 7, 5, 3, 0, 9}); + assertEquals(singletonList(2L), jsonV2.jsonArrIndexWithEscape("quxquux", ROOT_PATH, 7)); + assertEquals(singletonList(-1L), jsonV2.jsonArrIndexWithEscape("quxquux", ROOT_PATH, "7")); } @Test public void arrIndexWithStrings() { - jsonClient.jsonSetWithEscape("quxquux", ROOT_PATH, new String[]{"8", "6", "7", "5", "3", "0", "9"}); - assertEquals(singletonList(2L), jsonClient.jsonArrIndexWithEscape("quxquux", ROOT_PATH, "7")); + jsonV2.jsonSetWithEscape("quxquux", ROOT_PATH, new String[]{"8", "6", "7", "5", "3", "0", "9"}); + assertEquals(singletonList(2L), jsonV2.jsonArrIndexWithEscape("quxquux", ROOT_PATH, "7")); } @Test public void arrIndexWithStringsAndPath() { - jsonClient.jsonSetWithEscape("foobar", ROOT_PATH, new FooBarObject()); - assertEquals(singletonList(1L), jsonClient.jsonArrIndexWithEscape("foobar", Path2.of(".fooArr"), "b")); + jsonV2.jsonSetWithEscape("foobar", ROOT_PATH, new FooBarObject()); + assertEquals(singletonList(1L), jsonV2.jsonArrIndexWithEscape("foobar", Path2.of(".fooArr"), "b")); } @Test public void arrIndexNonExistentPath() { - jsonClient.jsonSet("foobar", ROOT_PATH, gson.toJson(new FooBarObject())); - assertEquals(Collections.emptyList(), jsonClient.jsonArrIndex("foobar", Path2.of(".barArr"), gson.toJson("x"))); + jsonV2.jsonSet("foobar", ROOT_PATH, gson.toJson(new FooBarObject())); + assertEquals(Collections.emptyList(), jsonV2.jsonArrIndex("foobar", Path2.of(".barArr"), gson.toJson("x"))); } @Test public void arrInsert() { String json = "['hello', 'world', true, 1, 3, null, false]"; - jsonClient.jsonSet("test_arrinsert", ROOT_PATH, new JSONArray(json)); - assertEquals(singletonList(8L), jsonClient.jsonArrInsertWithEscape("test_arrinsert", ROOT_PATH, 1, "foo")); + jsonV2.jsonSet("test_arrinsert", ROOT_PATH, new JSONArray(json)); + assertEquals(singletonList(8L), jsonV2.jsonArrInsertWithEscape("test_arrinsert", ROOT_PATH, 1, "foo")); assertJsonArrayEquals(jsonArray(jsonArray("hello", "foo", "world", true, 1, 3, null, false)), - jsonClient.jsonGet("test_arrinsert", ROOT_PATH)); + jsonV2.jsonGet("test_arrinsert", ROOT_PATH)); } @Test public void arrInsertWithNegativeIndex() { String json = "['hello', 'world', true, 1, 3, null, false]"; - jsonClient.jsonSet("test_arrinsert", ROOT_PATH, new JSONArray(json)); - assertEquals(singletonList(8L), jsonClient.jsonArrInsertWithEscape("test_arrinsert", ROOT_PATH, -1, "foo")); + jsonV2.jsonSet("test_arrinsert", ROOT_PATH, new JSONArray(json)); + assertEquals(singletonList(8L), jsonV2.jsonArrInsertWithEscape("test_arrinsert", ROOT_PATH, -1, "foo")); assertJsonArrayEquals(jsonArray(jsonArray("hello", "world", true, 1, 3, null, "foo", false)), - jsonClient.jsonGet("test_arrinsert", ROOT_PATH)); + jsonV2.jsonGet("test_arrinsert", ROOT_PATH)); } @Test public void arrPop() { - jsonClient.jsonSet("arr", ROOT_PATH, new JSONArray(new int[]{0, 1, 2, 3, 4})); - assertEquals(singletonList(4d), jsonClient.jsonArrPop("arr", ROOT_PATH)); - assertEquals(singletonList(3d), jsonClient.jsonArrPop("arr", ROOT_PATH, -1)); - assertEquals(singletonList(0d), jsonClient.jsonArrPop("arr", ROOT_PATH, 0)); + jsonV2.jsonSet("arr", ROOT_PATH, new JSONArray(new int[]{0, 1, 2, 3, 4})); + assertEquals(singletonList(4d), jsonV2.jsonArrPop("arr", ROOT_PATH)); + assertEquals(singletonList(3d), jsonV2.jsonArrPop("arr", ROOT_PATH, -1)); + assertEquals(singletonList(0d), jsonV2.jsonArrPop("arr", ROOT_PATH, 0)); } @Test public void arrTrim() { // jsonClient.jsonSet("arr", ROOT_PATH, new int[]{0, 1, 2, 3, 4}); - jsonClient.jsonSet("arr", ROOT_PATH, new JSONArray(new int[]{0, 1, 2, 3, 4})); - assertEquals(singletonList(3L), jsonClient.jsonArrTrim("arr", ROOT_PATH, 1, 3)); + jsonV2.jsonSet("arr", ROOT_PATH, new JSONArray(new int[]{0, 1, 2, 3, 4})); + assertEquals(singletonList(3L), jsonV2.jsonArrTrim("arr", ROOT_PATH, 1, 3)); // assertArrayEquals(new Integer[]{1, 2, 3}, jsonClient.jsonGet("arr", Integer[].class, ROOT_PATH)); - assertJsonArrayEquals(jsonArray(jsonArray(1, 2, 3)), jsonClient.jsonGet("arr", ROOT_PATH)); + assertJsonArrayEquals(jsonArray(jsonArray(1, 2, 3)), jsonV2.jsonGet("arr", ROOT_PATH)); } @Test public void strAppend() { // jsonClient.jsonSet("str", ROOT_PATH, "foo"); - jsonClient.jsonSet("str", ROOT_PATH, gson.toJson("foo")); - assertEquals(singletonList(6L), jsonClient.jsonStrAppend("str", ROOT_PATH, "bar")); - assertJsonArrayEquals(jsonArray("foobar"), jsonClient.jsonGet("str", ROOT_PATH)); + jsonV2.jsonSet("str", ROOT_PATH, gson.toJson("foo")); + assertEquals(singletonList(6L), jsonV2.jsonStrAppend("str", ROOT_PATH, "bar")); + assertJsonArrayEquals(jsonArray("foobar"), jsonV2.jsonGet("str", ROOT_PATH)); } @Test public void strLen() { - jsonClient.jsonSetWithEscape("str", "foobar"); - assertEquals(singletonList(6L), jsonClient.jsonStrLen("str", ROOT_PATH)); + jsonV2.jsonSetWithEscape("str", "foobar"); + assertEquals(singletonList(6L), jsonV2.jsonStrLen("str", ROOT_PATH)); } @Test public void numIncrBy() { Assume.assumeFalse(RedisProtocolUtil.getRedisProtocol() == RedisProtocol.RESP3); - jsonClient.jsonSet("doc", "{\"a\":\"b\",\"b\":[{\"a\":2}, {\"a\":5}, {\"a\":\"c\"}]}"); - assertJsonArrayEquals(jsonArray((Object) null), jsonClient.jsonNumIncrBy("doc", Path2.of(".a"), 1d)); - assertJsonArrayEquals(jsonArray(null, 4, 7, null), jsonClient.jsonNumIncrBy("doc", Path2.of("..a"), 2d)); - assertJsonArrayEquals(jsonArray((Object) null), jsonClient.jsonNumIncrBy("doc", Path2.of("..b"), 0d)); - assertJsonArrayEquals(jsonArray(), jsonClient.jsonNumIncrBy("doc", Path2.of("..c"), 0d)); + jsonV2.jsonSet("doc", "{\"a\":\"b\",\"b\":[{\"a\":2}, {\"a\":5}, {\"a\":\"c\"}]}"); + assertJsonArrayEquals(jsonArray((Object) null), jsonV2.jsonNumIncrBy("doc", Path2.of(".a"), 1d)); + assertJsonArrayEquals(jsonArray(null, 4, 7, null), jsonV2.jsonNumIncrBy("doc", Path2.of("..a"), 2d)); + assertJsonArrayEquals(jsonArray((Object) null), jsonV2.jsonNumIncrBy("doc", Path2.of("..b"), 0d)); + assertJsonArrayEquals(jsonArray(), jsonV2.jsonNumIncrBy("doc", Path2.of("..c"), 0d)); } @Test public void numIncrByResp3() { Assume.assumeTrue(RedisProtocolUtil.getRedisProtocol() == RedisProtocol.RESP3); - jsonClient.jsonSet("doc", "{\"a\":\"b\",\"b\":[{\"a\":2}, {\"a\":5}, {\"a\":\"c\"}]}"); - assertEquals(singletonList((Object) null), jsonClient.jsonNumIncrBy("doc", Path2.of(".a"), 1d)); - assertEquals(Arrays.asList(null, 4d, 7d, null), jsonClient.jsonNumIncrBy("doc", Path2.of("..a"), 2d)); - assertEquals(singletonList((Object) null), jsonClient.jsonNumIncrBy("doc", Path2.of("..b"), 0d)); - assertEquals(Collections.emptyList(), jsonClient.jsonNumIncrBy("doc", Path2.of("..c"), 0d)); + jsonV2.jsonSet("doc", "{\"a\":\"b\",\"b\":[{\"a\":2}, {\"a\":5}, {\"a\":\"c\"}]}"); + assertEquals(singletonList((Object) null), jsonV2.jsonNumIncrBy("doc", Path2.of(".a"), 1d)); + assertEquals(Arrays.asList(null, 4d, 7d, null), jsonV2.jsonNumIncrBy("doc", Path2.of("..a"), 2d)); + assertEquals(singletonList((Object) null), jsonV2.jsonNumIncrBy("doc", Path2.of("..b"), 0d)); + assertEquals(Collections.emptyList(), jsonV2.jsonNumIncrBy("doc", Path2.of("..c"), 0d)); } @Test public void obj() { String json = "{\"a\":[3], \"nested\": {\"a\": {\"b\":2, \"c\": 1}}}"; - jsonClient.jsonSet("doc", ROOT_PATH, json); - assertEquals(Arrays.asList(2L), jsonClient.jsonObjLen("doc", ROOT_PATH)); - assertEquals(Arrays.asList(Arrays.asList("a", "nested")), jsonClient.jsonObjKeys("doc", ROOT_PATH)); - assertEquals(Arrays.asList(null, 2L), jsonClient.jsonObjLen("doc", Path2.of("..a"))); - assertEquals(Arrays.asList(null, Arrays.asList("b", "c")), jsonClient.jsonObjKeys("doc", Path2.of("..a"))); + jsonV2.jsonSet("doc", ROOT_PATH, json); + assertEquals(Arrays.asList(2L), jsonV2.jsonObjLen("doc", ROOT_PATH)); + assertEquals(Arrays.asList(Arrays.asList("a", "nested")), jsonV2.jsonObjKeys("doc", ROOT_PATH)); + assertEquals(Arrays.asList(null, 2L), jsonV2.jsonObjLen("doc", Path2.of("..a"))); + assertEquals(Arrays.asList(null, Arrays.asList("b", "c")), jsonV2.jsonObjKeys("doc", Path2.of("..a"))); } @Test public void debugMemory() { - assertEquals(Collections.emptyList(), jsonClient.jsonDebugMemory("json", ROOT_PATH)); + assertEquals(Collections.emptyList(), jsonV2.jsonDebugMemory("json", ROOT_PATH)); - jsonClient.jsonSet("json", new JSONObject("{ foo: 'bar', bar: { foo: 10 }}")); - assertEquals(1, jsonClient.jsonDebugMemory("json", ROOT_PATH).size()); - assertEquals(2, jsonClient.jsonDebugMemory("json", Path2.of("$..foo")).size()); - assertEquals(1, jsonClient.jsonDebugMemory("json", Path2.of("$..bar")).size()); + jsonV2.jsonSet("json", new JSONObject("{ foo: 'bar', bar: { foo: 10 }}")); + assertEquals(1, jsonV2.jsonDebugMemory("json", ROOT_PATH).size()); + assertEquals(2, jsonV2.jsonDebugMemory("json", Path2.of("$..foo")).size()); + assertEquals(1, jsonV2.jsonDebugMemory("json", Path2.of("$..bar")).size()); } private void assertJsonArrayEquals(JSONArray a, Object _b) { diff --git a/src/test/java/redis/clients/jedis/modules/search/AggregationBuilderTest.java b/src/test/java/redis/clients/jedis/modules/search/AggregationBuilderTest.java new file mode 100644 index 0000000000..396ca3365e --- /dev/null +++ b/src/test/java/redis/clients/jedis/modules/search/AggregationBuilderTest.java @@ -0,0 +1,28 @@ +package redis.clients.jedis.modules.search; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +import redis.clients.jedis.search.aggr.Reducer; +import redis.clients.jedis.search.aggr.Reducers; + +public class AggregationBuilderTest { + + @Test + public void reducerObject() { + Reducer reducer = Reducers.sum("@count").as("total"); + assertEquals("SUM", reducer.getName()); + assertEquals("@count", reducer.getField()); + assertEquals("total", reducer.getAlias()); + } + + @Test + public void countObject() { + Reducer count = Reducers.count(); + assertEquals("COUNT", count.getName()); + assertNull(count.getField()); + assertNull(count.getAlias()); + } +} diff --git a/src/test/java/redis/clients/jedis/modules/search/QueryBuilderTest.java b/src/test/java/redis/clients/jedis/modules/search/QueryBuilderTest.java index a63b625f50..7f152f8985 100644 --- a/src/test/java/redis/clients/jedis/modules/search/QueryBuilderTest.java +++ b/src/test/java/redis/clients/jedis/modules/search/QueryBuilderTest.java @@ -91,10 +91,10 @@ public void testIntersectionBasic() { @Test public void testIntersectionNested() { - Node n = intersect(). - add(union("name", value("mark"), value("dvir"))). - add("time", between(100, 200)). - add(disjunct("created", lt(1000))); + Node n = intersect() + .add(union("name", value("mark"), value("dvir"))) + .add("time", between(100, 200)) + .add(disjunct("created", lt(1000))); assertEquals("(@name:(mark|dvir) @time:[100 200] -@created:[-inf (1000])", n.toString()); } diff --git a/src/test/java/redis/clients/jedis/modules/search/SearchWithParamsTest.java b/src/test/java/redis/clients/jedis/modules/search/SearchWithParamsTest.java index 98bc5968e8..a81ceb7821 100644 --- a/src/test/java/redis/clients/jedis/modules/search/SearchWithParamsTest.java +++ b/src/test/java/redis/clients/jedis/modules/search/SearchWithParamsTest.java @@ -1,14 +1,23 @@ package redis.clients.jedis.modules.search; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.*; import static redis.clients.jedis.util.AssertUtil.assertOK; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import org.hamcrest.Matchers; import org.junit.BeforeClass; import org.junit.Test; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKTReader; + import redis.clients.jedis.GeoCoordinate; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.args.GeoUnit; @@ -333,6 +342,100 @@ public void geoFilterAndGeoCoordinateObject() { assertEquals(2, res.getTotalResults()); } + @Test + public void geoShapeFilterSpherical() throws ParseException { + final WKTReader reader = new WKTReader(); + final GeometryFactory factory = new GeometryFactory(); + + assertOK(client.ftCreate(index, GeoShapeField.of("geom", GeoShapeField.CoordinateSystem.SPHERICAL))); + + // polygon type + final Polygon small = factory.createPolygon(new Coordinate[]{new Coordinate(34.9001, 29.7001), + new Coordinate(34.9001, 29.7100), new Coordinate(34.9100, 29.7100), + new Coordinate(34.9100, 29.7001), new Coordinate(34.9001, 29.7001)}); + client.hset("small", "geom", small.toString()); + + final Polygon large = factory.createPolygon(new Coordinate[]{new Coordinate(34.9001, 29.7001), + new Coordinate(34.9001, 29.7200), new Coordinate(34.9200, 29.7200), + new Coordinate(34.9200, 29.7001), new Coordinate(34.9001, 29.7001)}); + client.hset("large", "geom", large.toString()); + + // within condition + final Polygon within = factory.createPolygon(new Coordinate[]{new Coordinate(34.9000, 29.7000), + new Coordinate(34.9000, 29.7150), new Coordinate(34.9150, 29.7150), + new Coordinate(34.9150, 29.7000), new Coordinate(34.9000, 29.7000)}); + + SearchResult res = client.ftSearch(index, "@geom:[within $poly]", + FTSearchParams.searchParams().addParam("poly", within).dialect(3)); + assertEquals(1, res.getTotalResults()); + assertEquals(1, res.getDocuments().size()); + assertEquals(small, reader.read(res.getDocuments().get(0).getString("geom"))); + + // contains condition + final Polygon contains = factory.createPolygon(new Coordinate[]{new Coordinate(34.9002, 29.7002), + new Coordinate(34.9002, 29.7050), new Coordinate(34.9050, 29.7050), + new Coordinate(34.9050, 29.7002), new Coordinate(34.9002, 29.7002)}); + + res = client.ftSearch(index, "@geom:[contains $poly]", + FTSearchParams.searchParams().addParam("poly", contains).dialect(3)); + assertEquals(2, res.getTotalResults()); + assertEquals(2, res.getDocuments().size()); + + // point type + final Point point = factory.createPoint(new Coordinate(34.9010, 29.7010)); + client.hset("point", "geom", point.toString()); + + res = client.ftSearch(index, "@geom:[within $poly]", + FTSearchParams.searchParams().addParam("poly", within).dialect(3)); + assertEquals(2, res.getTotalResults()); + assertEquals(2, res.getDocuments().size()); + } + + @Test + public void geoShapeFilterFlat() throws ParseException { + final WKTReader reader = new WKTReader(); + final GeometryFactory factory = new GeometryFactory(); + + assertOK(client.ftCreate(index, GeoShapeField.of("geom", GeoShapeField.CoordinateSystem.FLAT))); + + // polygon type + final Polygon small = factory.createPolygon(new Coordinate[]{new Coordinate(1, 1), + new Coordinate(1, 100), new Coordinate(100, 100), new Coordinate(100, 1), new Coordinate(1, 1)}); + client.hset("small", "geom", small.toString()); + + final Polygon large = factory.createPolygon(new Coordinate[]{new Coordinate(1, 1), + new Coordinate(1, 200), new Coordinate(200, 200), new Coordinate(200, 1), new Coordinate(1, 1)}); + client.hset("large", "geom", large.toString()); + + // within condition + final Polygon within = factory.createPolygon(new Coordinate[]{new Coordinate(0, 0), + new Coordinate(0, 150), new Coordinate(150, 150), new Coordinate(150, 0), new Coordinate(0, 0)}); + + SearchResult res = client.ftSearch(index, "@geom:[within $poly]", + FTSearchParams.searchParams().addParam("poly", within).dialect(3)); + assertEquals(1, res.getTotalResults()); + assertEquals(1, res.getDocuments().size()); + assertEquals(small, reader.read(res.getDocuments().get(0).getString("geom"))); + + // contains condition + final Polygon contains = factory.createPolygon(new Coordinate[]{new Coordinate(2, 2), + new Coordinate(2, 50), new Coordinate(50, 50), new Coordinate(50, 2), new Coordinate(2, 2)}); + + res = client.ftSearch(index, "@geom:[contains $poly]", + FTSearchParams.searchParams().addParam("poly", contains).dialect(3)); + assertEquals(2, res.getTotalResults()); + assertEquals(2, res.getDocuments().size()); + + // point type + final Point point = factory.createPoint(new Coordinate(10, 10)); + client.hset("point", "geom", point.toString()); + + res = client.ftSearch(index, "@geom:[within $poly]", + FTSearchParams.searchParams().addParam("poly", within).dialect(3)); + assertEquals(2, res.getTotalResults()); + assertEquals(2, res.getDocuments().size()); + } + @Test public void testQueryFlags() { assertOK(client.ftCreate(index, TextField.of("title"))); @@ -1029,9 +1132,9 @@ public void maxPrefixExpansionSearchProfile() { client.ftConfigSet(configParam, "2"); assertOK(client.ftCreate(index, TextField.of("t"))); - client.hset("1", Collections.singletonMap("t", "foo1")); - client.hset("2", Collections.singletonMap("t", "foo2")); - client.hset("3", Collections.singletonMap("t", "foo3")); + client.hset("1", "t", "foo1"); + client.hset("2", "t", "foo2"); + client.hset("3", "t", "foo3"); Map.Entry> reply = client.ftProfileSearch(index, FTProfileParams.profileParams(), "foo*", FTSearchParams.searchParams().limit(0, 0)); @@ -1051,8 +1154,8 @@ public void maxPrefixExpansionSearchProfile() { @Test public void noContentSearchProfile() { assertOK(client.ftCreate(index, TextField.of("t"))); - client.hset("1", Collections.singletonMap("t", "foo")); - client.hset("2", Collections.singletonMap("t", "bar")); + client.hset("1", "t", "foo"); + client.hset("2", "t", "bar"); Map.Entry> profile = client.ftProfileSearch(index, FTProfileParams.profileParams(), "foo -@t:baz", FTSearchParams.searchParams().noContent()); @@ -1078,8 +1181,8 @@ public void noContentSearchProfile() { @Test public void deepReplySearchProfile() { assertOK(client.ftCreate(index, TextField.of("t"))); - client.hset("1", Collections.singletonMap("t", "hello")); - client.hset("2", Collections.singletonMap("t", "world")); + client.hset("1", "t", "hello"); + client.hset("2", "t", "world"); Map.Entry> profile = client.ftProfileSearch(index, FTProfileParams.profileParams(), @@ -1089,37 +1192,40 @@ public void deepReplySearchProfile() { ? (Map) profile.getValue().get("Iterators profile") : ((List>) profile.getValue().get("Iterators profile")).get(0); - assertEquals("INTERSECT", depth0.get("Type")); - List> depth0_children = (List>) depth0.get("Child iterators"); - assertEquals("TEXT", depth0_children.get(0).get("Type")); - Map depth1 = depth0_children.get(1); - assertEquals("INTERSECT", depth1.get("Type")); - List> depth1_children = (List>) depth1.get("Child iterators"); - assertEquals("TEXT", depth1_children.get(0).get("Type")); - Map depth2 = depth1_children.get(1); - assertEquals("INTERSECT", depth2.get("Type")); - List> depth2_children = (List>) depth2.get("Child iterators"); - assertEquals("TEXT", depth2_children.get(0).get("Type")); - Map depth3 = depth2_children.get(1); - assertEquals("INTERSECT", depth3.get("Type")); - List> depth3_children = (List>) depth3.get("Child iterators"); - assertEquals("TEXT", depth3_children.get(0).get("Type")); - Map depth4 = depth3_children.get(1); - assertEquals("INTERSECT", depth4.get("Type")); - List> depth4_children = (List>) depth4.get("Child iterators"); - assertEquals("TEXT", depth4_children.get(0).get("Type")); - Map depth5 = depth4_children.get(1); - assertEquals("TEXT", depth5.get("Type")); - assertNull(depth5.get("Child iterators")); + AtomicInteger intersectLevelCount = new AtomicInteger(); + AtomicInteger textLevelCount = new AtomicInteger(); + deepReplySearchProfile_assertProfile(depth0, intersectLevelCount, textLevelCount); + assertThat(intersectLevelCount.get(), Matchers.greaterThan(0)); + assertThat(textLevelCount.get(), Matchers.greaterThan(0)); + } + + private void deepReplySearchProfile_assertProfile(Map attr, + AtomicInteger intersectLevelCount, AtomicInteger textLevelCount) { + + String type = (String) attr.get("Type"); + assertThat(type, Matchers.not(Matchers.blankOrNullString())); + + switch (type) { + case "INTERSECT": + assertThat(attr, Matchers.hasKey("Child iterators")); + intersectLevelCount.incrementAndGet(); + deepReplySearchProfile_assertProfile((Map) ((List) attr.get("Child iterators")).get(0), + intersectLevelCount, textLevelCount); + break; + case "TEXT": + assertThat(attr, Matchers.hasKey("Term")); + textLevelCount.incrementAndGet(); + break; + } } @Test public void limitedSearchProfile() { assertOK(client.ftCreate(index, TextField.of("t"))); - client.hset("1", Collections.singletonMap("t", "hello")); - client.hset("2", Collections.singletonMap("t", "hell")); - client.hset("3", Collections.singletonMap("t", "help")); - client.hset("4", Collections.singletonMap("t", "helowa")); + client.hset("1", "t", "hello"); + client.hset("2", "t", "hell"); + client.hset("3", "t", "help"); + client.hset("4", "t", "helowa"); Map.Entry> profile = client.ftProfileSearch(index, FTProfileParams.profileParams().limited(), "%hell% hel*", FTSearchParams.searchParams().noContent()); @@ -1210,4 +1316,44 @@ public void searchIterationCollect() { "pupil:4444", "student:5555", "teacher:6666").stream().collect(Collectors.toSet()), collect.stream().map(Document::getId).collect(Collectors.toSet())); } + + @Test + public void escapeUtil() { + assertOK(client.ftCreate(index, TextField.of("txt"))); + + client.hset("doc1", "txt", RediSearchUtil.escape("hello-world")); + assertNotEquals("hello-world", client.hget("doc1", "txt")); + assertEquals("hello-world", RediSearchUtil.unescape(client.hget("doc1", "txt"))); + + SearchResult resultNoEscape = client.ftSearch(index, "hello-world"); + assertEquals(0, resultNoEscape.getTotalResults()); + + SearchResult resultEscaped = client.ftSearch(index, RediSearchUtil.escapeQuery("hello-world")); + assertEquals(1, resultEscaped.getTotalResults()); + } + + @Test + public void escapeMapUtil() { + client.hset("doc2", RediSearchUtil.toStringMap(Collections.singletonMap("txt", "hello-world"), true)); + assertNotEquals("hello-world", client.hget("doc2", "txt")); + assertEquals("hello-world", RediSearchUtil.unescape(client.hget("doc2", "txt"))); + } + + @Test + public void hsetObject() { + float[] floats = new float[]{0.2f}; + assertEquals(1L, client.hsetObject("obj", "floats", floats)); + assertArrayEquals(RediSearchUtil.toByteArray(floats), + client.hget("obj".getBytes(), "floats".getBytes())); + + GeoCoordinate geo = new GeoCoordinate(-0.441, 51.458); + Map fields = new HashMap<>(); + fields.put("title", "hello world"); + fields.put("loc", geo); + assertEquals(2L, client.hsetObject("obj", fields)); + Map stringMap = client.hgetAll("obj"); + assertEquals(3, stringMap.size()); + assertEquals("hello world", stringMap.get("title")); + assertEquals(geo.getLongitude() + "," + geo.getLatitude(), stringMap.get("loc")); + } } diff --git a/src/test/java/redis/clients/jedis/modules/search/UtilTest.java b/src/test/java/redis/clients/jedis/modules/search/UtilTest.java index d63c934a37..830b52565a 100644 --- a/src/test/java/redis/clients/jedis/modules/search/UtilTest.java +++ b/src/test/java/redis/clients/jedis/modules/search/UtilTest.java @@ -1,16 +1,32 @@ package redis.clients.jedis.modules.search; +import static org.junit.Assert.assertEquals; + import org.junit.Assert; import org.junit.Test; + import redis.clients.jedis.search.RediSearchUtil; +import redis.clients.jedis.search.schemafields.NumericField; +import redis.clients.jedis.search.schemafields.SchemaField; + public class UtilTest { @Test public void floatArrayToByteArray() { float[] floats = new float[]{0.2f}; - byte[] bytes = RediSearchUtil.ToByteArray(floats); + byte[] bytes = RediSearchUtil.toByteArray(floats); byte[] expected = new byte[]{-51, -52, 76, 62}; Assert.assertArrayEquals(expected, bytes); } + + @Test + public void getSchemaFieldName() { + SchemaField field = NumericField.of("$.num").as("num"); + + assertEquals("$.num", field.getFieldName().getName()); + assertEquals("num", field.getFieldName().getAttribute()); + + assertEquals("$.num", field.getName()); + } } diff --git a/src/test/resources/functions/keyspaceTriggers.js b/src/test/resources/functions/keyspaceTriggers.js new file mode 100644 index 0000000000..2bca56b4dc --- /dev/null +++ b/src/test/resources/functions/keyspaceTriggers.js @@ -0,0 +1,12 @@ +#!js api_version=1.0 name=keyspaceTriggers + +redis.registerKeySpaceTrigger("consumer", "", function(client, data){ + if (client.call("type", data.key) != "hash") { + // key is not a hash, do not touch it. + return; + } + // get the current time in ms + var curr_time = client.call("time")[0]; + // set '__last_updated__' with the current time value + client.call('hset', data.key, '__last_updated__', curr_time); +}); \ No newline at end of file diff --git a/src/test/resources/functions/pingpong.js b/src/test/resources/functions/pingpong.js new file mode 100644 index 0000000000..511013ce16 --- /dev/null +++ b/src/test/resources/functions/pingpong.js @@ -0,0 +1,7 @@ +#!js api_version=1.0 name=pingpong + +function answer(client, data) { + return client.call('ping'); +} + +redis.registerFunction('playPingPong', answer, {description: 'You PING, we PONG'}); \ No newline at end of file diff --git a/src/test/resources/functions/streamTriggers.js b/src/test/resources/functions/streamTriggers.js new file mode 100644 index 0000000000..9d39020d1e --- /dev/null +++ b/src/test/resources/functions/streamTriggers.js @@ -0,0 +1,14 @@ +#!js api_version=1.0 name=streamTriggers + +redis.registerStreamTrigger( + "consumer", // consumer name + "stream", // streams prefix + function(c, data) { + // callback to run on each element added to the stream + redis.log(JSON.stringify(data, (key, value) => + typeof value === 'bigint' + ? value.toString() + : value // return everything else unchanged + )); + } +); \ No newline at end of file diff --git a/src/test/resources/functions/withConfig.js b/src/test/resources/functions/withConfig.js new file mode 100644 index 0000000000..c06944864f --- /dev/null +++ b/src/test/resources/functions/withConfig.js @@ -0,0 +1,16 @@ +#!js api_version=1.0 name=withConfig + +var last_modified_field_name = "__last_modified__" + +if (redis.config.last_modified_field_name !== undefined) { + if (typeof redis.config.last_modified_field_name != 'string') { + throw "last_modified_field_name must be a string"; + } + last_modified_field_name = redis.config.last_modified_field_name +} + +redis.registerFunction("hset", function(client, key, field, val){ + // get the current time in ms + var curr_time = client.call("time")[0]; + return client.call('hset', key, field, val, last_modified_field_name, curr_time); +}); \ No newline at end of file diff --git a/src/test/resources/functions/withFlags.js b/src/test/resources/functions/withFlags.js new file mode 100644 index 0000000000..f4f9f05e1f --- /dev/null +++ b/src/test/resources/functions/withFlags.js @@ -0,0 +1,9 @@ +#!js api_version=1.0 name=withFlags +redis.registerFunction("my_set", + (c, key, val) => { + return c.call("set", key, val); + }, + { + flags: [redis.functionFlags.RAW_ARGUMENTS] + } +); \ No newline at end of file diff --git a/src/test/resources/functions/workingWIthHashes.js b/src/test/resources/functions/workingWIthHashes.js new file mode 100644 index 0000000000..6b99c51655 --- /dev/null +++ b/src/test/resources/functions/workingWIthHashes.js @@ -0,0 +1,8 @@ +#!js api_version=1.0 name=hashitout + +redis.registerFunction('hashy', function(client, key_name){ + if (client.call('type', key_name) == 'hash') { + return client.call('hgetall', key_name); + } + throw "Oops, that wasn't a Hash!"; +}); \ No newline at end of file