use of com.alipay.sofa.rpc.codec.Serializer in project sofa-rpc by sofastack.
the class AbstractHttp2ClientTransport method doSend.
protected void doSend(final SofaRequest request, AbstractHttpClientHandler callback, final int timeoutMills) {
AbstractByteBuf data = null;
try {
// 序列化
byte serializeType = request.getSerializeType();
Serializer serializer = SerializerFactory.getSerializer(serializeType);
data = serializer.encode(request, null);
request.setData(data);
// 记录请求序列化大小 不是很准,没有记录HTTP头
RpcInternalContext.getContext().setAttachment(RpcConstants.INTERNAL_KEY_REQ_SIZE, data.readableBytes());
// 转换请求
FullHttpRequest httpRequest = convertToHttpRequest(request);
// 发送请求
final int requestId = sendHttpRequest(httpRequest, callback);
if (request.isAsync()) {
TIMEOUT_TIMER.newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
Map.Entry<ChannelFuture, AbstractHttpClientHandler> entry = responseChannelHandler.removePromise(requestId);
if (entry != null) {
ClientHandler handler = entry.getValue();
Exception e = timeoutException(request, timeoutMills, null);
handler.onException(e);
}
}
}, timeoutMills, TimeUnit.MILLISECONDS);
}
} finally {
if (data != null) {
data.release();
}
}
}
use of com.alipay.sofa.rpc.codec.Serializer in project sofa-rpc by sofastack.
the class AbstractHttpServerTask method run.
@Override
public void run() {
// RPC内置上下文
RpcInternalContext context = RpcInternalContext.getContext();
context.setProviderSide(true);
String appName = request.getTargetAppName();
if (appName == null) {
// 默认全局appName
appName = (String) RpcRuntimeContext.get(RpcRuntimeContext.KEY_APPNAME);
}
try {
// 这个 try-finally 为了保证Context一定被清理
Channel channel = ctx.channel();
// 远程地址
context.setRemoteAddress((InetSocketAddress) channel.remoteAddress());
// 远程返回的通道
context.setAttachment(RpcConstants.HIDDEN_KEY_ASYNC_CONTEXT, channel);
if (EventBus.isEnable(ServerReceiveEvent.class)) {
EventBus.post(new ServerReceiveEvent(request));
}
// 开始处理
// 响应,用于返回
SofaResponse response = null;
// 异常,用于记录
Throwable throwable = null;
HttpResponseStatus status = null;
ProviderConfig providerConfig = null;
String serviceName = request.getTargetServiceUniqueName();
Serializer serializer = null;
if (request.getSerializeType() > 0) {
serializer = SerializerFactory.getSerializer(request.getSerializeType());
}
try {
// 这个try-catch 保证一定有Response
invoke: {
// 查找服务
Invoker invoker = serverHandler.getInvokerMap().get(serviceName);
if (invoker == null) {
throwable = cannotFoundService(appName, serviceName);
response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
status = HttpResponseStatus.NOT_FOUND;
break invoke;
}
if (invoker instanceof ProviderProxyInvoker) {
providerConfig = ((ProviderProxyInvoker) invoker).getProviderConfig();
// 找到服务后,打印服务的appName
appName = providerConfig != null ? providerConfig.getAppName() : null;
}
// 查找方法
String methodName = request.getMethodName();
Method serviceMethod = serverHandler.getMethod(serviceName, methodName);
if (serviceMethod == null) {
throwable = cannotFoundServiceMethod(appName, methodName, serviceName);
response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
status = HttpResponseStatus.NOT_FOUND;
break invoke;
} else {
request.setMethod(serviceMethod);
}
AbstractByteBuf reqData = request.getData();
if (reqData != null) {
try {
Map<String, String> map = new HashMap<String, String>(4);
map.put(RemotingConstants.HEAD_TARGET_SERVICE, request.getTargetServiceUniqueName());
map.put(RemotingConstants.HEAD_METHOD_NAME, request.getMethodName());
map.put(RemotingConstants.HEAD_TARGET_APP, request.getTargetAppName());
serializer.decode(reqData, request, map);
} catch (Exception e) {
LOGGER.errorWithApp(appName, "Server deserialize error, request from " + channel.remoteAddress(), e);
response = MessageBuilder.buildSofaErrorResponse("Server deserialize error, " + e.getMessage());
break invoke;
}
} else if (request.getMethodArgs() == null) {
request.setMethodArgs(CodecUtils.EMPTY_OBJECT_ARRAY);
}
// 真正调用
response = doInvoke(serviceName, invoker, request);
}
} catch (Exception e) {
// 服务端异常,不管是啥异常
LOGGER.errorWithApp(appName, "Server Processor Error!", e);
throwable = e;
response = MessageBuilder.buildSofaErrorResponse(e.getMessage());
status = HttpResponseStatus.INTERNAL_SERVER_ERROR;
}
// Response不为空,代表需要返回给客户端
if (response != null) {
response.setSerializeType(request.getSerializeType());
// 其它正常请求
try {
// 这个try-catch 保证一定要记录tracer
if (response.isError()) {
ByteBuf content = ctx.alloc().buffer();
content.writeBytes(StringSerializer.encode(response.getErrorMsg()));
sendRpcError(status == null ? HttpResponseStatus.INTERNAL_SERVER_ERROR : status, content);
} else {
if (response.getAppResponse() instanceof Throwable) {
ByteBuf content = ctx.alloc().buffer();
String errorMsg = ExceptionUtils.toString((Throwable) response.getAppResponse());
content.writeBytes(StringSerializer.encode(errorMsg));
sendAppError(HttpResponseStatus.OK, content);
} else {
ByteBuf content = ctx.alloc().buffer();
if (request.getSerializeType() > 0) {
AbstractByteBuf bs = serializer.encode(response, null);
content.writeBytes(bs.array());
} else {
content.writeBytes(StringSerializer.encode(response.getAppResponse().toString()));
}
sendAppResponse(HttpResponseStatus.OK, content);
}
}
} finally {
if (EventBus.isEnable(ServerSendEvent.class)) {
EventBus.post(new ServerSendEvent(request, response, throwable));
}
}
}
} catch (Throwable e) {
// 可能有返回时的异常
if (LOGGER.isErrorEnabled(appName)) {
LOGGER.errorWithApp(appName, e.getMessage(), e);
}
} finally {
serverHandler.getProcessingCount().decrementAndGet();
if (EventBus.isEnable(ServerEndHandleEvent.class)) {
EventBus.post(new ServerEndHandleEvent());
}
RpcInvokeContext.removeContext();
RpcInternalContext.removeAllContext();
}
}
use of com.alipay.sofa.rpc.codec.Serializer in project sofa-rpc by sofastack.
the class SofaRpcSerialization method deserializeContent.
@Override
public <Request extends RequestCommand> boolean deserializeContent(Request request) throws DeserializationException {
if (request instanceof RpcRequestCommand) {
RpcRequestCommand requestCommand = (RpcRequestCommand) request;
Object header = requestCommand.getRequestHeader();
if (!(header instanceof Map)) {
throw new DeserializationException("Head of request is null or is not map");
}
Map<String, String> headerMap = (Map<String, String>) header;
String traceId = headerMap.get("rpc_trace_context.sofaTraceId");
String rpcId = headerMap.get("rpc_trace_context.sofaRpcId");
long deserializeStartTime = System.nanoTime();
try {
byte[] content = requestCommand.getContent();
if (content == null || content.length == 0) {
throw new DeserializationException("Content of request is null");
}
String service = headerMap.get(RemotingConstants.HEAD_SERVICE);
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader serviceClassLoader = ReflectCache.getServiceClassLoader(service);
try {
Thread.currentThread().setContextClassLoader(serviceClassLoader);
Serializer rpcSerializer = com.alipay.sofa.rpc.codec.SerializerFactory.getSerializer(requestCommand.getSerializer());
Object sofaRequest = ClassUtils.forName(requestCommand.getRequestClass()).newInstance();
rpcSerializer.decode(new ByteArrayWrapperByteBuf(requestCommand.getContent()), sofaRequest, headerMap);
// for service mesh or other scene, we need to add more info from header
if (sofaRequest instanceof SofaRequest) {
setRequestPropertiesWithHeaderInfo(headerMap, (SofaRequest) sofaRequest);
parseRequestHeader(headerMap, (SofaRequest) sofaRequest);
}
requestCommand.setRequestObject(sofaRequest);
} finally {
Thread.currentThread().setContextClassLoader(oldClassLoader);
}
return true;
} catch (Exception ex) {
LOGGER.error("traceId={}, rpcId={}, Request deserializeContent exception, msg={}", traceId, rpcId, ex.getMessage(), ex);
throw new DeserializationException(ex.getMessage() + ", traceId=" + traceId + ", rpcId=" + rpcId, ex);
} finally {
// R6:Record request deserialization time
recordDeserializeRequest(requestCommand, deserializeStartTime);
}
}
return false;
}
use of com.alipay.sofa.rpc.codec.Serializer in project sofa-rpc by sofastack.
the class SofaRpcSerialization method deserializeContent.
@Override
public <Response extends ResponseCommand> boolean deserializeContent(Response response, InvokeContext invokeContext) throws DeserializationException {
if (response instanceof RpcResponseCommand) {
RpcResponseCommand responseCommand = (RpcResponseCommand) response;
byte serializer = response.getSerializer();
byte[] content = responseCommand.getContent();
if (content == null || content.length == 0) {
return false;
}
long deserializeStartTime = System.nanoTime();
try {
Object sofaResponse = ClassUtils.forName(responseCommand.getResponseClass()).newInstance();
Map<String, String> header = (Map<String, String>) responseCommand.getResponseHeader();
if (header == null) {
header = new HashMap<String, String>();
}
putKV(header, RemotingConstants.HEAD_TARGET_SERVICE, (String) invokeContext.get(RemotingConstants.HEAD_TARGET_SERVICE));
putKV(header, RemotingConstants.HEAD_METHOD_NAME, (String) invokeContext.get(RemotingConstants.HEAD_METHOD_NAME));
putKV(header, RemotingConstants.HEAD_GENERIC_TYPE, (String) invokeContext.get(RemotingConstants.HEAD_GENERIC_TYPE));
Serializer rpcSerializer = com.alipay.sofa.rpc.codec.SerializerFactory.getSerializer(serializer);
rpcSerializer.decode(new ByteArrayWrapperByteBuf(responseCommand.getContent()), sofaResponse, header);
if (sofaResponse instanceof SofaResponse) {
parseResponseHeader(header, (SofaResponse) sofaResponse);
}
responseCommand.setResponseObject(sofaResponse);
return true;
} catch (Exception ex) {
throw new DeserializationException(ex.getMessage(), ex);
} finally {
// R5:Record response deserialization time
recordDeserializeResponse(responseCommand, invokeContext, deserializeStartTime);
}
}
return false;
}
use of com.alipay.sofa.rpc.codec.Serializer in project sofa-rpc by sofastack.
the class GenericServiceImpl method generic.
@Override
public void generic(Request request, StreamObserver<Response> responseObserver) {
SofaRequest sofaRequest = TracingContextKey.getKeySofaRequest().get(Context.current());
String methodName = sofaRequest.getMethodName();
String interfaceName = sofaRequest.getInterfaceName();
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
try {
Class proxyClass = ClassTypeUtils.getClass(interfaceName);
ClassLoader interfaceClassLoader = proxyClass.getClassLoader();
Thread.currentThread().setContextClassLoader(interfaceClassLoader);
Class[] argTypes = getArgTypes(request);
Serializer serializer = SerializerFactory.getSerializer(request.getSerializeType());
Method declaredMethod = proxyClass.getDeclaredMethod(methodName, argTypes);
Object[] invokeArgs = getInvokeArgs(request, argTypes, serializer);
// fill sofaRequest
sofaRequest.setMethod(declaredMethod);
sofaRequest.setMethodArgs(invokeArgs);
sofaRequest.setMethodArgSigs(ClassTypeUtils.getTypeStrs(argTypes, true));
SofaResponse response = invoker.invoke(sofaRequest);
Object ret = getAppResponse(declaredMethod, response);
Response.Builder builder = Response.newBuilder();
builder.setSerializeType(request.getSerializeType());
builder.setType(declaredMethod.getReturnType().getName());
builder.setData(ByteString.copyFrom(serializer.encode(ret, null).array()));
Response build = builder.build();
responseObserver.onNext(build);
responseObserver.onCompleted();
} catch (Exception e) {
LOGGER.error("Invoke " + methodName + " error:", e);
throw new SofaRpcRuntimeException(e);
} finally {
Thread.currentThread().setContextClassLoader(oldClassLoader);
}
}
Aggregations