Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java: Add GET & SET commands #919

Merged

Conversation

acarbonetto
Copy link
Collaborator

Issue #, if available:

Description of changes:

This PR is dependent on: #917

This PR adds get/set/ping/info calls to the standalone, and cluster-mode:

  • standalone
    • get
    • set
    • set with options
  • cluster
    • get
    • set
    • set with options

Examples:

// Single commands
RedisClient client = RedisClient.createClient(config).get();
Ok setResult = client.set("key", "value").get(); // returns "OK"
String getResult = client.get("key").get(); // returns "value"

// Cluster-mode single commands
RedisClusterClient clusterClient = RedisClusterClient.createClient(config).get();
Ok setResult = clusterClient.set("key", "value").get(); // returns "OK"
String getResult = clusterClient.get("key").get(); // returns "value"

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@acarbonetto acarbonetto requested a review from a team as a code owner February 7, 2024 22:48
@acarbonetto acarbonetto self-assigned this Feb 8, 2024
@acarbonetto acarbonetto added the java issues and fixes related to the java client label Feb 8, 2024
@acarbonetto acarbonetto force-pushed the java/integ_acarbo_add_getset_only branch from 0a10654 to 65c893a Compare February 8, 2024 21:10
@@ -31,6 +31,6 @@ public static CompletableFuture<RedisClient> CreateClient(RedisClientConfigurati

@Override
public CompletableFuture<Object> customCommand(String[] args) {
return commandManager.submitNewCommand(CustomCommand, args, this::handleObjectResponse);
return commandManager.submitNewCommand(CustomCommand, args, this::handleObjectOrNullResponse);
Copy link
Collaborator Author

@acarbonetto acarbonetto Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed function handleObjectOrNullResponse() to be consistent with how sometimes we allow for null and sometimes not.

Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
@acarbonetto acarbonetto force-pushed the java/integ_acarbo_add_getset_only branch from e17fec0 to b445dc6 Compare February 9, 2024 06:38
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
* If <code>conditionalSet</code> is not set the value will be set regardless of prior value
* existence. If value isn't set because of the condition, command will return <code>null</code>.
*/
private final ConditionalSet conditionalSet;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be an optional, in order to properly represent that this value can be not set.
It's better to make types explicit than rely on enum being null, which is a (weird) language specific ability.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Objects in the @Builder pattern are all optional unless defaulted (@Builder.Default). If not set, the value will be null. I dislike using nulls, but as part of a Builder, we can contain the pattern and trust Lombok.
Unfortunately, Lombok doesn't play well with Optionals (actually, the Lombok developers actively dislike the Optional pattern). We would have to create our own Builders to work with Optionals, or we can stick with what Lombok provides and use nulls if the value isn't set prior.

private final boolean returnOldValue;

/** If not set, no expiry time will be set for the value. */
private final Expiry expiry;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

* The amount of time to live before the key expires. Ignored when {@link
* ExpiryType#KEEP_EXISTING} type is set.
*/
private Long count;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't a Duration type be more representative of the data?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, yes. This object is not being used to calculate duration, but to map to string for a Set command.
But this just a map to the Set command (which takes a number/Integer). Documentation says "Integer", but Bar commented that Long is more appropriate.
see: https://redis.io/commands/set/

* @param value The value to store with the given <code>key</code>.
* @return Response from Redis containing <code>"OK"</code>.
*/
CompletableFuture<String> set(String key, String value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the arguments be marked with @NonNull?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The annotation is an implementation detail. It doesn't do anything in the interface.
I can add it for "documentation" purposes?

@ParameterizedTest
@MethodSource("getClients")
public void set_requires_a_value(BaseClient client) {
assertThrows(NullPointerException.class, () -> client.set("SET", null));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor - the null exception tests can be in UTs, not ITs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

San can move these to the next PR?

Signed-off-by: Andrew Carbonetto <[email protected]>
@acarbonetto acarbonetto merged commit 8f35f5a into valkey-io:main Feb 9, 2024
11 checks passed
@acarbonetto acarbonetto deleted the java/integ_acarbo_add_getset_only branch February 9, 2024 20:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
java issues and fixes related to the java client
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants