![JAR search and dependency download from the Maven repository](/logo.png)
org.infinispan.server.resp.commands.connection.CLIENT Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of infinispan-server-resp Show documentation
Show all versions of infinispan-server-resp Show documentation
Infinispan Resp Protocol Server
package org.infinispan.server.resp.commands.connection;
import static org.infinispan.server.resp.Util.utf8;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletionStage;
import java.util.regex.Pattern;
import org.infinispan.security.AuthorizationPermission;
import org.infinispan.security.Security;
import org.infinispan.server.core.transport.ConnectionMetadata;
import org.infinispan.server.core.transport.NettyTransport;
import org.infinispan.server.resp.Resp3Handler;
import org.infinispan.server.resp.RespCommand;
import org.infinispan.server.resp.RespErrorUtil;
import org.infinispan.server.resp.RespRequestHandler;
import org.infinispan.server.resp.commands.Resp3Command;
import org.infinispan.server.resp.serialization.Resp3Response;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.ChannelMatcher;
/**
* CLIENT *
*
* @since 15.0
*/
public class CLIENT extends RespCommand implements Resp3Command {
// We accept a String that matches from the start to end, only contains ASCII characters that are not blank.
private static final Pattern CLIENT_SETINFO_PATTERN = Pattern.compile("^(?:(?=\\p{ASCII})[^\\s\\t\\n\\x0B\\f\\r])*$");
public CLIENT() {
super(-2, 0, 0, 0);
}
@Override
public CompletionStage perform(Resp3Handler handler, ChannelHandlerContext ctx,
List arguments) {
String subcommand = utf8(arguments.get(0)).toUpperCase();
ConnectionMetadata metadata = ConnectionMetadata.getInstance(ctx.channel());
switch (subcommand) {
case "CACHING":
case "UNPAUSE":
case "PAUSE":
case "NO-EVICT":
case "KILL":
case "NO-TOUCH":
case "GETREDIR":
case "UNBLOCK":
case "REPLY":
RespErrorUtil.customError("unsupported command", handler.allocator());
break;
case "SETINFO":
for (int i = 1; i < arguments.size(); i++) {
String name = utf8(arguments.get(i));
switch (name.toUpperCase()) {
case "LIB-NAME":
String libName = utf8(arguments.get(++i));
if (!CLIENT_SETINFO_PATTERN.matcher(libName).matches()) {
RespErrorUtil.customError("lib-name cannot contain spaces, newlines or special characters.", handler.allocator());
return handler.myStage();
}
metadata.clientLibraryName(libName);
break;
case "LIB-VER":
String libVer = utf8(arguments.get(++i));
if (!CLIENT_SETINFO_PATTERN.matcher(libVer).matches()) {
RespErrorUtil.customError("lib-ver cannot contain spaces, newlines or special characters.", handler.allocator());
return handler.myStage();
}
metadata.clientLibraryVersion(libVer);
break;
default:
RespErrorUtil.customError("unsupported attribute " + name, handler.allocator());
return handler.myStage();
}
}
Resp3Response.ok(handler.allocator());
break;
case "SETNAME":
metadata.clientName(utf8(arguments.get(1)));
Resp3Response.ok(handler.allocator());
break;
case "GETNAME":
// This could be UTF-8
Resp3Response.string(metadata.clientName(), handler.allocator());
break;
case "ID":
Resp3Response.integers(metadata.id(), handler.allocator());
break;
case "INFO": {
StringBuilder sb = new StringBuilder();
addInfo(sb, metadata);
// This could be UTF-8
Resp3Response.string(sb, handler.allocator());
break;
}
case "LIST": {
handler.checkPermission(AuthorizationPermission.ADMIN);
StringBuilder sb = new StringBuilder();
ChannelMatcher matcher = handler.respServer().getChannelMatcher();
NettyTransport transport = handler.respServer().getTransport();
if (transport == null) {
transport = (NettyTransport) handler.respServer().getEnclosingProtocolServer().getTransport();
}
ChannelGroup channels = transport.getAcceptedChannels();
channels.forEach(ch -> {
if (matcher.matches(ch)) {
addInfo(sb, ConnectionMetadata.getInstance(ch));
}
});
Resp3Response.string(sb, handler.allocator());
break;
}
case "TRACKING":
RespErrorUtil.customError("client tracking not supported", handler.allocator());
break;
case "TRACKINGINFO":
Resp3Response.map(Collections.emptyMap(), handler.allocator());
break;
}
return handler.myStage();
}
private void addInfo(StringBuilder sb, ConnectionMetadata metadata) {
sb.append("id=");
sb.append(metadata.id());
sb.append(" addr=");
sb.append(metadata.remoteAddress());
sb.append(" laddr=");
sb.append(metadata.localAddress());
sb.append(" name=");
String name = metadata.clientName();
if (name != null) {
sb.append(name);
}
String libName = metadata.clientLibraryName();
sb.append(" lib-name=").append(libName != null ? libName : "");
String libVer = metadata.clientLibraryVersion();
sb.append(" lib-ver=").append(libVer != null ? libVer : "");
sb.append(" age=");
sb.append(Duration.between(metadata.created(), Instant.now()).getSeconds());
sb.append(" db=");
sb.append(metadata.cache());
sb.append(" user=");
sb.append(Security.getSubjectUserPrincipalName(metadata.subject()));
sb.append(" resp=3");
sb.append("\n");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy