forked from valkey-io/valkey-glide
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Java - Add custom command interface; and BaseCommands (valkey-io#837)
* Java - Add custom command interface; and BaseCommands (#58) * Add base command; add custom command --------- Signed-off-by: Andrew Carbonetto <[email protected]> * Clean up merge conflict Signed-off-by: Andrew Carbonetto <[email protected]> * Move Command resolvers to manager level Signed-off-by: Andrew Carbonetto <[email protected]> * Remove ClusterClient.java Signed-off-by: Andrew Carbonetto <[email protected]> * Spotless Signed-off-by: Andrew Carbonetto <[email protected]> * Update CommandManager comment Signed-off-by: Andrew Carbonetto <[email protected]> * Minor comments Signed-off-by: Andrew Carbonetto <[email protected]> * Move commands and response handlers to protected locations Signed-off-by: Andrew Carbonetto <[email protected]> * Clean up imports Signed-off-by: Andrew Carbonetto <[email protected]> * Update custom command documentation Signed-off-by: Andrew Carbonetto <[email protected]> * Update javadoc for RedisExceptionCheckedFunction Signed-off-by: Andrew Carbonetto <[email protected]> --------- Signed-off-by: Andrew Carbonetto <[email protected]>
- Loading branch information
1 parent
2bb441d
commit 9345634
Showing
10 changed files
with
487 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
java/client/src/main/java/glide/api/commands/BaseCommands.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package glide.api.commands; | ||
|
||
import java.util.concurrent.CompletableFuture; | ||
|
||
/** Base Commands interface to handle generic command and transaction requests. */ | ||
public interface BaseCommands { | ||
|
||
/** | ||
* Executes a single command, without checking inputs. Every part of the command, including | ||
* subcommands, should be added as a separate value in args. | ||
* | ||
* @remarks This function should only be used for single-response commands. Commands that don't | ||
* return response (such as SUBSCRIBE), or that return potentially more than a single response | ||
* (such as XREAD), or that change the client's behavior (such as entering pub/sub mode on | ||
* RESP2 connections) shouldn't be called using this function. | ||
* @example Returns a list of all pub/sub clients: | ||
* <pre> | ||
* Object result = client.customCommand(new String[]{"CLIENT","LIST","TYPE", "PUBSUB"}).get(); | ||
* </pre> | ||
* | ||
* @param args arguments for the custom command | ||
* @return a CompletableFuture with response result from Redis | ||
*/ | ||
CompletableFuture<Object> customCommand(String[] args); | ||
} |
68 changes: 68 additions & 0 deletions
68
java/client/src/main/java/glide/managers/BaseCommandResponseResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package glide.managers; | ||
|
||
import glide.api.models.exceptions.ClosingException; | ||
import glide.api.models.exceptions.ConnectionException; | ||
import glide.api.models.exceptions.ExecAbortException; | ||
import glide.api.models.exceptions.RedisException; | ||
import glide.api.models.exceptions.RequestException; | ||
import glide.api.models.exceptions.TimeoutException; | ||
import lombok.AllArgsConstructor; | ||
import response.ResponseOuterClass.RequestError; | ||
import response.ResponseOuterClass.Response; | ||
|
||
/** | ||
* Response resolver responsible for evaluating the Redis response object with a success or failure. | ||
*/ | ||
@AllArgsConstructor | ||
public class BaseCommandResponseResolver | ||
implements RedisExceptionCheckedFunction<Response, Object> { | ||
|
||
private RedisExceptionCheckedFunction<Long, Object> respPointerResolver; | ||
|
||
/** | ||
* Extracts value from the RESP pointer. <br> | ||
* Throws errors when the response is unsuccessful. | ||
* | ||
* @return A generic Object with the Response | null if the response is empty | ||
*/ | ||
public Object apply(Response response) throws RedisException { | ||
if (response.hasRequestError()) { | ||
RequestError error = response.getRequestError(); | ||
String msg = error.getMessage(); | ||
switch (error.getType()) { | ||
case Unspecified: | ||
// Unspecified error on Redis service-side | ||
throw new RequestException(msg); | ||
case ExecAbort: | ||
// Transactional error on Redis service-side | ||
throw new ExecAbortException(msg); | ||
case Timeout: | ||
// Timeout from Glide to Redis service | ||
throw new TimeoutException(msg); | ||
case Disconnect: | ||
// Connection problem between Glide and Redis | ||
throw new ConnectionException(msg); | ||
default: | ||
// Request or command error from Redis | ||
throw new RequestException(msg); | ||
} | ||
} | ||
if (response.hasClosingError()) { | ||
// A closing error is thrown when Rust-core is not connected to Redis | ||
// We want to close shop and throw a ClosingException | ||
// TODO: close the channel on a closing error | ||
// channel.close(); | ||
throw new ClosingException(response.getClosingError()); | ||
} | ||
if (response.hasConstantResponse()) { | ||
// Return "OK" | ||
return response.getConstantResponse().toString(); | ||
} | ||
if (response.hasRespPointer()) { | ||
// Return the shared value - which may be a null value | ||
return respPointerResolver.apply(response.getRespPointer()); | ||
} | ||
// if no response payload is provided, assume null | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
java/client/src/main/java/glide/managers/RedisExceptionCheckedFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package glide.managers; | ||
|
||
import glide.api.models.exceptions.RedisException; | ||
|
||
/** | ||
* Functional Interface to convert values and throw RedisException when encountering an error state. | ||
* | ||
* @param <R> type to evaluate | ||
* @param <T> payload type | ||
*/ | ||
@FunctionalInterface | ||
public interface RedisExceptionCheckedFunction<R, T> { | ||
|
||
/** | ||
* Functional response handler that takes a value of type R and returns a payload of type T. | ||
* Throws RedisException when encountering an invalid or error state. | ||
* | ||
* @param value - received value type | ||
* @return T - returning payload type | ||
* @throws RedisException | ||
*/ | ||
T apply(R value) throws RedisException; | ||
} |
24 changes: 24 additions & 0 deletions
24
java/client/src/main/java/glide/managers/models/Command.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package glide.managers.models; | ||
|
||
import lombok.Builder; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.NonNull; | ||
|
||
/** Base Command class to send a single request to Redis. */ | ||
@Builder | ||
@Getter | ||
@EqualsAndHashCode | ||
public class Command { | ||
|
||
/** Redis command request type */ | ||
@NonNull final RequestType requestType; | ||
|
||
/** List of Arguments for the Redis command request */ | ||
@Builder.Default final String[] arguments = new String[] {}; | ||
|
||
public enum RequestType { | ||
/** Call a custom command with list of string arguments */ | ||
CUSTOM_COMMAND, | ||
} | ||
} |
Oops, something went wrong.