package org.infinispan.server.hotrod; import static org.infinispan.server.hotrod.ResponseWriting.writeResponse; import java.security.PrivilegedExceptionAction; import javax.security.auth.Subject; import org.infinispan.security.Security; import org.infinispan.server.core.transport.NettyTransport; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** * Handler that performs actual cache operations. Note this handler should be on a separate executor group than the * decoder. * * @author wburns * @since 9.0 */ public class LocalContextHandler extends ChannelInboundHandlerAdapter { private final NettyTransport transport; public LocalContextHandler(NettyTransport transport) { this.transport = transport; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof CacheDecodeContext) { CacheDecodeContext cdc = (CacheDecodeContext) msg; Subject subject = ((CacheDecodeContext) msg).subject; if (subject == null) realChannelRead(ctx, msg, cdc); else Security.doAs(subject, (PrivilegedExceptionAction<Void>) () -> { realChannelRead(ctx, msg, cdc); return null; }); } else { super.channelRead(ctx, msg); } } private void realChannelRead(ChannelHandlerContext ctx, Object msg, CacheDecodeContext cdc) throws Exception { HotRodHeader h = cdc.header; switch (h.op) { case CONTAINS_KEY: writeResponse(cdc, ctx.channel(), cdc.containsKey()); break; case GET: case GET_WITH_VERSION: writeResponse(cdc, ctx.channel(), cdc.get()); break; case GET_WITH_METADATA: writeResponse(cdc, ctx.channel(), cdc.getKeyMetadata()); break; case PING: writeResponse(cdc, ctx.channel(), new EmptyResponse(h.version, h.messageId, h.cacheName, h.clientIntel, HotRodOperation.PING, OperationStatus.Success, h.topologyId)); break; case STATS: writeResponse(cdc, ctx.channel(), cdc.decoder.createStatsResponse(cdc, transport)); break; default: super.channelRead(ctx, msg); } } }