Search in sources :

Example 1 with RpcRequest

use of org.msec.rpc.RpcRequest in project MSEC by Tencent.

the class RequestEncoder method encode.

@Override
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
    if (msg instanceof RpcRequest) {
        RpcRequest message = (RpcRequest) msg;
        try {
            ChannelBufferOutputStream bout = new ChannelBufferOutputStream(ChannelBuffers.dynamicBuffer(estimatedLength, ctx.getChannel().getConfig().getBufferFactory()));
            // Set proto flag = 0
            NettyCodecUtils.setAttachment(ctx, Constants.ATTACHMENT_CUSTOM_PROTO_FLAG, new Integer(0));
            ChannelBuffer ret = encode(ctx, message, bout);
            return ret;
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            throw ex;
        }
    }
    if (msg instanceof Object[]) {
        Object[] objects = (Object[]) msg;
        // Set proto flag=1
        NettyCodecUtils.setAttachment(ctx, Constants.ATTACHMENT_CUSTOM_PROTO_FLAG, new Integer(1));
        NettyCodecUtils.setAttachment(ctx, Constants.ATTACHMENT_CUSTOM_PROTO_CODEC, objects[1]);
        NettyCodecUtils.setAttachment(ctx, Constants.ATTACHMENT_CUSTOM_PROTO_SEQUENCE, objects[2]);
        if (objects[0] instanceof byte[]) {
            byte[] msgData = (byte[]) objects[0];
            int tmpLength = estimatedLength;
            if (msgData.length > tmpLength) {
                tmpLength = msgData.length;
            }
            ChannelBufferOutputStream bout = new ChannelBufferOutputStream(ChannelBuffers.dynamicBuffer(tmpLength, ctx.getChannel().getConfig().getBufferFactory()));
            bout.write(msgData);
            return bout.buffer();
        } else {
            return objects[0];
        }
    }
    return null;
}
Also used : ChannelBufferOutputStream(org.jboss.netty.buffer.ChannelBufferOutputStream) RpcRequest(org.msec.rpc.RpcRequest) IOException(java.io.IOException) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer)

Example 2 with RpcRequest

use of org.msec.rpc.RpcRequest in project MSEC by Tencent.

the class RequestDecoder method decode.

@Override
protected Object decode(ChannelHandlerContext channelHandlerContext, Channel channel, Object msg) throws Exception {
    long receiveTime = System.currentTimeMillis();
    if (!(msg instanceof ChannelBuffer)) {
        return msg;
    }
    ChannelBuffer cb = (ChannelBuffer) NettyCodecUtils.getAttachment(channelHandlerContext, Constants.ATTACHMENT_BYTEBUFFER);
    ChannelBuffer cb_ = (ChannelBuffer) msg;
    if (cb == null) {
        cb = cb_;
    } else {
        cb.writeBytes(cb_);
    }
    List<Object> messages = null;
    int lastReadIndex = cb.readerIndex();
    int deserializeMode = -1;
    while (cb.readable()) {
        byte stx = cb.readByte();
        RpcRequest rpcRequest = null;
        if (stx == (byte) '(') {
            if (cb.readableBytes() < Constants.PKG_LEAST_LENGTH - 1) {
                setAttachment(channelHandlerContext, channel, cb, lastReadIndex);
                break;
            }
            // Test whether protocol is protobuf
            // Format:  ( + dwHeadLength + dwBodyLength + strHead + strBody + )
            int headLength = cb.readInt();
            int bodyLength = cb.readInt();
            if (cb.readableBytes() < headLength + bodyLength + 1) {
                setAttachment(channelHandlerContext, channel, cb, lastReadIndex);
                break;
            }
            byte[] headBytes = new byte[headLength];
            byte[] bodyBytes = new byte[bodyLength];
            cb.readBytes(headBytes);
            cb.readBytes(bodyBytes);
            byte etx = cb.readByte();
            if (etx != ')') {
                log.error("Invalid package etx.");
                throw new IllegalArgumentException("Request decode error: invalid package etx " + etx);
            }
            // parse protobuf package
            rpcRequest = deserializeProtobufPackage(headBytes, bodyBytes);
            rpcRequest.setSerializeMode(RpcRequest.SerializeMode.SERIALIZE_MODE_PROTOBUF);
        } else {
            // Test whether protocol is HTTP
            cb.readerIndex(lastReadIndex);
            int totalLength = cb.readableBytes();
            byte[] totalBytes = new byte[totalLength];
            cb.readBytes(totalBytes);
            String total = new String(totalBytes);
            int pos = total.indexOf("\r\n\r\n");
            if (pos < 0) {
                setAttachment(channelHandlerContext, channel, cb, lastReadIndex);
                break;
            }
            int contentLength = getHTTPContentLength(total.substring(0, pos + 4));
            if (totalLength < pos + 4 + contentLength) {
                setAttachment(channelHandlerContext, channel, cb, lastReadIndex);
                break;
            }
            cb.readerIndex(pos + 4 + contentLength);
            // parse HTTP package
            rpcRequest = deserializeHTTPPackage(total.substring(0, pos + 4 + contentLength));
            rpcRequest.setSerializeMode(RpcRequest.SerializeMode.SERIALIZE_MODE_HTTP);
        }
        if (rpcRequest != null) {
            if (messages == null) {
                messages = new ArrayList<Object>();
            }
            messages.add(rpcRequest);
            lastReadIndex = cb.readerIndex();
        } else {
            setAttachment(channelHandlerContext, channel, cb, lastReadIndex);
            break;
        }
    }
    return messages;
}
Also used : RpcRequest(org.msec.rpc.RpcRequest) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) DynamicChannelBuffer(org.jboss.netty.buffer.DynamicChannelBuffer)

Example 3 with RpcRequest

use of org.msec.rpc.RpcRequest in project MSEC by Tencent.

the class RequestDecoder method deserializeProtobufPackage.

private RpcRequest deserializeProtobufPackage(byte[] headBytes, byte[] bodyBytes) {
    Head.CRpcHead pbHead = null;
    RpcRequest rpcRequest = new RpcRequest();
    try {
        pbHead = Head.CRpcHead.parseFrom(headBytes);
        rpcRequest.setSeq(pbHead.getSequence());
    } catch (InvalidProtocolBufferException e) {
        log.error("Parse protobuf head failed.");
        rpcRequest.setException(new IllegalArgumentException("Parse protobuf head failed."));
        return rpcRequest;
    }
    String serviceMethodName = pbHead.getMethodName().toStringUtf8();
    int pos = serviceMethodName.lastIndexOf('.');
    if (pos == -1 || pos == 0 || pos == serviceMethodName.length() - 1) {
        log.error("Invalid serviceMethodName (" + serviceMethodName + "). Must be in format like *.*");
        rpcRequest.setException(new IllegalArgumentException("Invalid serviceMethodName (" + serviceMethodName + "). Must be in format like *.*"));
        return rpcRequest;
    }
    String serviceName = serviceMethodName.substring(0, pos);
    String methodName = serviceMethodName.substring(pos + 1);
    rpcRequest.setServiceName(serviceName);
    rpcRequest.setMethodName(methodName);
    rpcRequest.setFlowid(pbHead.getFlowId());
    if (pbHead.getCaller() != null && !pbHead.getCaller().isEmpty()) {
        rpcRequest.setFromModule(pbHead.getCaller().toStringUtf8());
    } else {
        rpcRequest.setFromModule("UnknownModule");
    }
    // If flowid == 0, we must generate one
    if (rpcRequest.getFlowid() == 0) {
        rpcRequest.setFlowid(rpcRequest.getSeq() ^ NettyCodecUtils.generateColorId(serviceMethodName));
    }
    AccessMonitor.add("frm.rpc request incoming: " + methodName);
    ServiceFactory.ServiceMethodEntry serviceMethodEntry = ServiceFactory.getServiceMethodEntry(serviceName, methodName);
    if (serviceMethodEntry == null) {
        log.error("No service method registered: " + rpcRequest.getServiceName() + "/" + rpcRequest.getMethodName());
        rpcRequest.setException(new IllegalArgumentException("No service method registered: " + rpcRequest.getServiceName() + "/" + rpcRequest.getMethodName()));
        return rpcRequest;
    }
    MessageLite param = null;
    try {
        param = (MessageLite) serviceMethodEntry.getParamTypeParser().parseFrom(bodyBytes);
    } catch (InvalidProtocolBufferException ex) {
        log.error("Parse protobuf body failed.");
        rpcRequest.setException(new IllegalArgumentException("RParse protobuf body failed." + ex.getMessage()));
        return rpcRequest;
    }
    rpcRequest.setParameter(param);
    log.info("RPC Request received. ServiceMethodName: " + rpcRequest.getServiceName() + "/" + rpcRequest.getMethodName() + "\tSeq: " + rpcRequest.getSeq() + "\tParameter: " + rpcRequest.getParameter());
    return rpcRequest;
}
Also used : Head(srpc.Head) ServiceFactory(org.msec.rpc.ServiceFactory) RpcRequest(org.msec.rpc.RpcRequest) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) MessageLite(com.google.protobuf.MessageLite)

Example 4 with RpcRequest

use of org.msec.rpc.RpcRequest in project MSEC by Tencent.

the class RequestDecoder method deserializeHTTPPackage.

private RpcRequest deserializeHTTPPackage(String request) {
    RpcRequest rpcRequest = new RpcRequest();
    HttpRequestParser httpParser = new HttpRequestParser();
    try {
        httpParser.parseRequest(request);
    } catch (IOException ex) {
        log.error("HTTP Request parse failed." + ex.getMessage());
        rpcRequest.setException(new IllegalArgumentException("Request decode error: HTTP Request parse failed." + ex.getMessage()));
        return rpcRequest;
    } catch (HttpFormatException ex) {
        log.error("HTTP Request parse failed." + ex.getMessage());
        rpcRequest.setException(new IllegalArgumentException("Request decode error: HTTP Request parse failed." + ex.getMessage()));
        return rpcRequest;
    }
    rpcRequest.setHttpCgiName(httpParser.getCgiPath());
    if (httpParser.getCgiPath().compareToIgnoreCase("/list") == 0) {
        return rpcRequest;
    }
    if (httpParser.getCgiPath().compareToIgnoreCase("/invoke") != 0) {
        log.error("HTTP cgi not found: " + httpParser.getCgiPath());
        rpcRequest.setException(new IllegalArgumentException("HTTP cgi not found: " + httpParser.getURI()));
        return rpcRequest;
    }
    String serviceMethodName = httpParser.getQueryString("methodName");
    int pos = serviceMethodName.lastIndexOf('.');
    if (pos == -1 || pos == 0 || pos == serviceMethodName.length() - 1) {
        log.error("Invalid serviceMethodName (" + serviceMethodName + "). Must be in format like *.*");
        rpcRequest.setException(new IllegalArgumentException("Invalid serviceMethodName (" + serviceMethodName + "). Must be in format like *.*"));
        return rpcRequest;
    }
    String serviceName = serviceMethodName.substring(0, pos);
    String methodName = serviceMethodName.substring(pos + 1);
    String seq = httpParser.getQueryString("seq");
    String param = httpParser.getQueryString("param");
    if (param == null || param.isEmpty()) {
        param = httpParser.getMessageBody();
    }
    try {
        param = java.net.URLDecoder.decode(param, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        param = "";
    }
    rpcRequest.setServiceName(serviceName);
    rpcRequest.setMethodName(methodName);
    if (seq == null || seq.isEmpty()) {
        rpcRequest.setSeq(ServiceFactory.generateSequence());
    } else {
        rpcRequest.setSeq(Long.valueOf(seq).longValue());
    }
    log.info("In HTTP package service: " + serviceName + " method: " + methodName + " param: " + param);
    rpcRequest.setFromModule("UnknownModule");
    rpcRequest.setFlowid(rpcRequest.getSeq() ^ NettyCodecUtils.generateColorId(serviceName + methodName));
    AccessMonitor.add("frm.rpc request incoming: " + methodName);
    ServiceFactory.ServiceMethodEntry serviceMethodEntry = ServiceFactory.getServiceMethodEntry(serviceName, methodName);
    if (serviceMethodEntry == null) {
        log.error("No service method registered: " + rpcRequest.getServiceName() + "/" + rpcRequest.getMethodName());
        rpcRequest.setException(new IllegalArgumentException("No service method registered: " + rpcRequest.getServiceName() + "/" + rpcRequest.getMethodName()));
        return rpcRequest;
    }
    Message.Builder builder = serviceMethodEntry.getParamTypeBuilder();
    try {
        builder.clear();
        JsonFormat.merge(param, builder);
    } catch (JsonFormat.ParseException ex) {
        log.error("Json parse failed." + ex.getMessage());
        rpcRequest.setException(new IllegalArgumentException("Request decode error: Json parse failed." + ex.getMessage()));
        return rpcRequest;
    }
    if (!builder.isInitialized()) {
        log.error("Json to Protobuf failed: missing required fields");
        rpcRequest.setException(new IllegalArgumentException("Json to Protobuf failed: missing required fields: " + builder.getInitializationErrorString()));
        return rpcRequest;
    }
    rpcRequest.setParameter(builder.build());
    log.info("RPC Request received. ServiceMethodName: " + rpcRequest.getServiceName() + "/" + rpcRequest.getMethodName() + "\tSeq: " + rpcRequest.getSeq() + "\tParameter: " + rpcRequest.getParameter());
    return rpcRequest;
}
Also used : Message(com.google.protobuf.Message) ServiceFactory(org.msec.rpc.ServiceFactory) HttpRequestParser(org.msec.rpc.HttpRequestParser) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) JsonFormat(com.googlecode.protobuf.format.JsonFormat) HttpFormatException(org.msec.rpc.HttpFormatException) RpcRequest(org.msec.rpc.RpcRequest)

Aggregations

RpcRequest (org.msec.rpc.RpcRequest)4 IOException (java.io.IOException)2 ChannelBuffer (org.jboss.netty.buffer.ChannelBuffer)2 ServiceFactory (org.msec.rpc.ServiceFactory)2 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1 Message (com.google.protobuf.Message)1 MessageLite (com.google.protobuf.MessageLite)1 JsonFormat (com.googlecode.protobuf.format.JsonFormat)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 ChannelBufferOutputStream (org.jboss.netty.buffer.ChannelBufferOutputStream)1 DynamicChannelBuffer (org.jboss.netty.buffer.DynamicChannelBuffer)1 HttpFormatException (org.msec.rpc.HttpFormatException)1 HttpRequestParser (org.msec.rpc.HttpRequestParser)1 Head (srpc.Head)1