Package redis.server.netty

Source Code of redis.server.netty.RedisCommandHandler$Wrapper

package redis.server.netty;

import com.google.common.base.Charsets;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import redis.netty4.Command;
import redis.netty4.ErrorReply;
import redis.netty4.InlineReply;
import redis.netty4.Reply;
import redis.util.BytesKey;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import static redis.netty4.ErrorReply.NYI_REPLY;
import static redis.netty4.StatusReply.QUIT;

/**
* Handle decoded commands
*/
@ChannelHandler.Sharable
public class RedisCommandHandler extends SimpleChannelInboundHandler<Command> {

  private Map<BytesKey, Wrapper> methods = new HashMap<BytesKey, Wrapper>();

  interface Wrapper {
    Reply execute(Command command) throws RedisException;
  }

  public RedisCommandHandler(final RedisServer rs) {
    Class<? extends RedisServer> aClass = rs.getClass();
    for (final Method method : aClass.getMethods()) {
      final Class<?>[] types = method.getParameterTypes();
      methods.put(new BytesKey(method.getName().getBytes()), new Wrapper() {
        @Override
        public Reply execute(Command command) throws RedisException {
          Object[] objects = new Object[types.length];
          try {
            command.toArguments(objects, types);
            return (Reply) method.invoke(rs, objects);
          } catch (IllegalAccessException e) {
            throw new RedisException("Invalid server implementation");
          } catch (InvocationTargetException e) {
            Throwable te = e.getTargetException();
            if (!(te instanceof RedisException)) {
              te.printStackTrace();
            }
            return new ErrorReply("ERR " + te.getMessage());
          } catch (Exception e) {
            return new ErrorReply("ERR " + e.getMessage());
          }
        }
      });
    }
  }

  private static final byte LOWER_DIFF = 'a' - 'A';

  @Override
  public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    ctx.flush();
  }

  @Override
  protected void channelRead0(ChannelHandlerContext ctx, Command msg) throws Exception {
    byte[] name = msg.getName();
    for (int i = 0; i < name.length; i++) {
      byte b = name[i];
      if (b >= 'A' && b <= 'Z') {
        name[i] = (byte) (b + LOWER_DIFF);
      }
    }
    Wrapper wrapper = methods.get(new BytesKey(name));
    Reply reply;
    if (wrapper == null) {
      reply = new ErrorReply("unknown command '" + new String(name, Charsets.US_ASCII) + "'");
    } else {
      reply = wrapper.execute(msg);
    }
    if (reply == QUIT) {
      ctx.close();
    } else {
      if (msg.isInline()) {
        if (reply == null) {
          reply = new InlineReply(null);
        } else {
          reply = new InlineReply(reply.data());
        }
      }
      if (reply == null) {
        reply = NYI_REPLY;
      }
      ctx.write(reply);
    }
  }
}
TOP

Related Classes of redis.server.netty.RedisCommandHandler$Wrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.