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;
}
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;
}
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;
}
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;
}
Aggregations