Skip to content

Commit

Permalink
Add CLIENT ID and CLIENT GETNAME commands. (#98)
Browse files Browse the repository at this point in the history
* Add `CLIENT ID` and `CLIENT GETNAME` commands.

Signed-off-by: Yury-Fridlyand <[email protected]>
  • Loading branch information
Yury-Fridlyand authored Feb 21, 2024
1 parent 2b9f9f7 commit 68ba1a0
Show file tree
Hide file tree
Showing 12 changed files with 392 additions and 38 deletions.
19 changes: 16 additions & 3 deletions java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import static glide.ffi.resolvers.SocketListenerResolver.getSocket;
import static glide.utils.ArrayTransformUtils.castArray;
import static glide.utils.ArrayTransformUtils.convertMapToArgArray;
import static redis_request.RedisRequestOuterClass.RequestType.ClientGetName;
import static redis_request.RedisRequestOuterClass.RequestType.ClientId;
import static redis_request.RedisRequestOuterClass.RequestType.Decr;
import static redis_request.RedisRequestOuterClass.RequestType.DecrBy;
import static redis_request.RedisRequestOuterClass.RequestType.GetString;
Expand All @@ -22,7 +24,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.SRem;
import static redis_request.RedisRequestOuterClass.RequestType.SetString;

import glide.api.commands.ConnectionManagementCommands;
import glide.api.commands.ConnectionManagementBaseCommands;
import glide.api.commands.HashCommands;
import glide.api.commands.SetCommands;
import glide.api.commands.StringCommands;
Expand Down Expand Up @@ -53,10 +55,11 @@
@AllArgsConstructor
public abstract class BaseClient
implements AutoCloseable,
ConnectionManagementCommands,
ConnectionManagementBaseCommands,
StringCommands,
HashCommands,
SetCommands {

/** Redis simple string response with "OK" */
public static final String OK = ConstantResponse.OK.toString();

Expand Down Expand Up @@ -188,7 +191,7 @@ protected Object[] handleArrayOrNullResponse(Response response) throws RedisExce
/**
* @param response A Protobuf response
* @return A map of <code>String</code> to <code>V</code>
* @param <V> Value type could be even map too
* @param <V> Value type, could be even map too
*/
@SuppressWarnings("unchecked") // raw Map cast to Map<String, V>
protected <V> Map<String, V> handleMapResponse(Response response) throws RedisException {
Expand Down Expand Up @@ -309,4 +312,14 @@ public CompletableFuture<Set<String>> smembers(String key) {
public CompletableFuture<Long> scard(String key) {
return commandManager.submitNewCommand(SCard, new String[] {key}, this::handleLongResponse);
}

public CompletableFuture<Long> clientId() {
return commandManager.submitNewCommand(ClientId, new String[0], this::handleLongResponse);
}

@Override
public CompletableFuture<String> clientGetName() {
return commandManager.submitNewCommand(
ClientGetName, new String[0], this::handleStringOrNullResponse);
}
}
13 changes: 13 additions & 0 deletions java/client/src/main/java/glide/api/RedisClient.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */
package glide.api;

import static redis_request.RedisRequestOuterClass.RequestType.ClientGetName;
import static redis_request.RedisRequestOuterClass.RequestType.ClientId;
import static redis_request.RedisRequestOuterClass.RequestType.CustomCommand;
import static redis_request.RedisRequestOuterClass.RequestType.Info;

Expand Down Expand Up @@ -54,4 +56,15 @@ public CompletableFuture<String> info() {
public CompletableFuture<String> info(@NonNull InfoOptions options) {
return commandManager.submitNewCommand(Info, options.toArgs(), this::handleStringResponse);
}

@Override
public CompletableFuture<Long> clientId() {
return commandManager.submitNewCommand(ClientId, new String[0], this::handleLongResponse);
}

@Override
public CompletableFuture<String> clientGetName() {
return commandManager.submitNewCommand(
ClientGetName, new String[0], this::handleStringOrNullResponse);
}
}
39 changes: 38 additions & 1 deletion java/client/src/main/java/glide/api/RedisClusterClient.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */
package glide.api;

import static redis_request.RedisRequestOuterClass.RequestType.ClientGetName;
import static redis_request.RedisRequestOuterClass.RequestType.ClientId;
import static redis_request.RedisRequestOuterClass.RequestType.CustomCommand;
import static redis_request.RedisRequestOuterClass.RequestType.Info;
import static redis_request.RedisRequestOuterClass.RequestType.Ping;
Expand Down Expand Up @@ -53,7 +55,8 @@ public CompletableFuture<ClusterValue<Object>> customCommand(@NonNull String[] a
}

@Override
public CompletableFuture<ClusterValue<Object>> customCommand(String[] args, Route route) {
public CompletableFuture<ClusterValue<Object>> customCommand(
@NonNull String[] args, @NonNull Route route) {
return commandManager.submitNewCommand(
CustomCommand, args, route, response -> handleCustomCommandResponse(route, response));
}
Expand Down Expand Up @@ -132,4 +135,38 @@ public CompletableFuture<ClusterValue<String>> info(
? ClusterValue.of(handleStringResponse(response))
: ClusterValue.of(handleMapResponse(response)));
}

@Override
public CompletableFuture<Long> clientId() {
return super.clientId();
}

@Override
public CompletableFuture<ClusterValue<Long>> clientId(@NonNull Route route) {
return commandManager.submitNewCommand(
ClientId,
new String[0],
route,
response ->
route.isSingleNodeRoute()
? ClusterValue.of(handleLongResponse(response))
: ClusterValue.of(handleMapResponse(response)));
}

@Override
public CompletableFuture<String> clientGetName() {
return super.clientGetName();
}

@Override
public CompletableFuture<ClusterValue<String>> clientGetName(@NonNull Route route) {
return commandManager.submitNewCommand(
ClientGetName,
new String[0],
route,
response ->
route.isSingleNodeRoute()
? ClusterValue.of(handleStringOrNullResponse(response))
: ClusterValue.of(handleMapResponse(response)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */
package glide.api.commands;

import java.util.concurrent.CompletableFuture;

/**
* Connection Management Commands interface for both standalone and cluster clients.
*
* @see <a href="https://redis.io/commands/?group=connection">Connection Management Commands</a>
*/
public interface ConnectionManagementBaseCommands {

/**
* Ping the Redis server.
*
* @see <a href="https://redis.io/commands/ping/">redis.io</a> for details.
* @return Response from Redis containing a <code>String</code> with "PONG".
*/
CompletableFuture<String> ping();

/**
* Ping the Redis server.
*
* @see <a href="https://redis.io/commands/ping/">redis.io</a> for details.
* @param str The ping argument that will be returned.
* @return Response from Redis containing a <code>String</code> with a copy of the argument <code>
* str</code>.
*/
CompletableFuture<String> ping(String str);

/**
* Gets the current connection id.
*
* @see <a href="https://redis.io/commands/client-id/">redis.io</a> for details.
* @return The id of the client.
* @example
* <pre>
* long id = client.clientId().get();
* assert id > 0
* </pre>
*/
CompletableFuture<Long> clientId();

/**
* Gets the name of the current connection.
*
* @see <a href="https://redis.io/commands/client-getname/">redis.io</a> for details.
* @return The name of the client connection as a string if a name is set, or <code>null</code> if
* no name is assigned.
* @example
* <pre>
* String clientName = client.clientGetName().get();
* assert clientName != null
* </pre>
*/
CompletableFuture<String> clientGetName();
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */
package glide.api.commands;

import glide.api.models.ClusterValue;
import glide.api.models.configuration.RequestRoutingConfiguration.Route;
import java.util.concurrent.CompletableFuture;

/**
* Connection Management Commands interface.
* Connection Management Commands interface for cluster client.
*
* @see: <a href="https://redis.io/commands/?group=connection">Connection Management Commands</a>
* @see <a href="https://redis.io/commands/?group=connection">Connection Management Commands</a>
*/
public interface ConnectionManagementClusterCommands {

Expand All @@ -32,4 +33,80 @@ public interface ConnectionManagementClusterCommands {
* str</code>.
*/
CompletableFuture<String> ping(String str, Route route);

/**
* Gets the current connection id.<br>
* The command will be routed a random node.
*
* @see <a href="https://redis.io/commands/client-id/">redis.io</a> for details.
* @return The id of the client.
* @example
* <pre>
* long id = client.clientId().get();
* assert id > 0
* </pre>
*/
CompletableFuture<Long> clientId();

/**
* Gets the current connection id.
*
* @see <a href="https://redis.io/commands/client-id/">redis.io</a> for details.
* @param route Routing configuration for the command. Client will route the command to the nodes
* defined.
* @return A {@link ClusterValue} which holds a single value if single node route is used or a
* dictionary where each address is the key and its corresponding node response is the value.
* The value is the id of the client on that node.
* @example
* <pre>
* long id = client.clientId(new SlotIdRoute(...)).get().getSingleValue();
* assert id > 0
* </pre>
*
* @example
* <pre>
* Map&lt;String, Long&gt; idPerNode = client.clientId(ALL_NODES).get().getMultiValue();
* assert idPerNode.get("&lt;node 1 address&gt;") > 0
* </pre>
*/
CompletableFuture<ClusterValue<Long>> clientId(Route route);

/**
* Gets the name of the current connection.<br>
* The command will be routed a random node.
*
* @see <a href="https://redis.io/commands/client-getname/">redis.io</a> for details.
* @return The name of the client connection as a string if a name is set, or <code>null</code> if
* no name is assigned.
* @example
* <pre>
* String clientName = client.clientGetName().get();
* assert clientName != null
* </pre>
*/
CompletableFuture<String> clientGetName();

/**
* Gets the name of the current connection.
*
* @see <a href="https://redis.io/commands/client-getname/">redis.io</a> for details.
* @param route Routing configuration for the command. Client will route the command to the nodes
* defined.
* @return A {@link ClusterValue} which holds a single value if single node route is used or a
* dictionary where each address is the key and its corresponding node response is the value.
* The value is the name of the client connection as a string if a name is set, or null if no
* name is assigned.
* @example
* <pre>
* String clientName = client.clientGetName(new SlotIdRoute(...)).get().getSingleValue();
* assert clientName != null
* </pre>
*
* @example
* <pre>
* Map&lt;String, String&gt; clientNamePerNode = client.clientGetName(ALL_NODES).get().getMultiValue();
* assert clientNamePerNode.get("&lt;node 1 address&gt;") != null
* </pre>
*/
CompletableFuture<ClusterValue<String>> clientGetName(Route route);
}

This file was deleted.

25 changes: 25 additions & 0 deletions java/client/src/main/java/glide/api/models/BaseTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
package glide.api.models;

import static glide.utils.ArrayTransformUtils.convertMapToArgArray;
import static redis_request.RedisRequestOuterClass.RequestType.ClientGetName;
import static redis_request.RedisRequestOuterClass.RequestType.ClientId;
import static redis_request.RedisRequestOuterClass.RequestType.CustomCommand;
import static redis_request.RedisRequestOuterClass.RequestType.Decr;
import static redis_request.RedisRequestOuterClass.RequestType.DecrBy;
Expand Down Expand Up @@ -413,6 +415,29 @@ public T scard(String key) {
return getThis();
}

/**
* Get the current connection id.
*
* @see <a href="https://redis.io/commands/client-id/">redis.io</a> for details.
* @return Command response - The id of the client.
*/
public T clientId() {
protobufTransaction.addCommands(buildCommand(ClientId));
return getThis();
}

/**
* Get the name of the current connection.
*
* @see <a href="https://redis.io/commands/client-getname/">redis.io</a> for details.
* @return Command response - The name of the client connection as a string if a name is set, or
* <code>null</code> if no name is assigned.
*/
public T clientGetName() {
protobufTransaction.addCommands(buildCommand(ClientGetName));
return getThis();
}

/** Build protobuf {@link Command} object for given command and arguments. */
protected Command buildCommand(RequestType requestType) {
return buildCommand(requestType, buildArgs());
Expand Down
Loading

0 comments on commit 68ba1a0

Please sign in to comment.