use of com.alipay.sofa.rpc.core.response.SofaResponse in project sofa-rpc by sofastack.
the class ProviderInvoker method invoke.
@Override
public SofaResponse invoke(SofaRequest request) throws SofaRpcException {
/*// 将接口的<sofa:param />的配置复制到RpcInternalContext
RpcInternalContext context = RpcInternalContext.getContext();
Map params = providerConfig.getParameters();
if (params != null) {
context.setAttachments(params);
}
// 将方法的<sofa:param />的配置复制到invocation
String methodName = request.getMethodName();
params = (Map) providerConfig.getMethodConfigValue(methodName, SofaConstants.CONFIG_KEY_PARAMS);
if (params != null) {
context.setAttachments(params);
}*/
SofaResponse sofaResponse = new SofaResponse();
long startTime = RpcRuntimeContext.now();
long bizStartTime = System.nanoTime();
RpcInvokeContext.getContext().put(RpcConstants.INTERNAL_KEY_PROVIDER_INVOKE_START_TIME_NANO, System.nanoTime());
try {
// 反射 真正调用业务代码
Method method = request.getMethod();
if (method == null) {
throw new SofaRpcException(RpcErrorType.SERVER_FILTER, LogCodes.getLog(LogCodes.ERROR_NEED_DECODE_METHOD));
}
Object result = method.invoke(providerConfig.getRef(), request.getMethodArgs());
sofaResponse.setAppResponse(result);
} catch (IllegalArgumentException e) {
// 非法参数,可能是实现类和接口类不对应)
sofaResponse.setErrorMsg(e.getMessage());
} catch (IllegalAccessException e) {
// 如果此 Method 对象强制执行 Java 语言访问控制,并且底层方法是不可访问的
sofaResponse.setErrorMsg(e.getMessage());
// } catch (NoSuchMethodException e) { // 如果找不到匹配的方法
// sofaResponse.setErrorMsg(e.getMessage());
// } catch (ClassNotFoundException e) { // 如果指定的类加载器无法定位该类
// sofaResponse.setErrorMsg(e.getMessage());
} catch (InvocationTargetException e) {
// 业务代码抛出异常
cutCause(e.getCause());
sofaResponse.setAppResponse(e.getCause());
} finally {
// R8: Record business processing execution time
if (RpcInternalContext.isAttachmentEnable()) {
long endTime = RpcRuntimeContext.now();
RpcInternalContext.getContext().setAttachment(RpcConstants.INTERNAL_KEY_IMPL_ELAPSE, endTime - startTime);
}
RpcInvokeContext.getContext().put(RpcConstants.INTERNAL_KEY_IMPL_ELAPSE_NANO, System.nanoTime() - bizStartTime);
RpcInvokeContext.getContext().put(RpcConstants.INTERNAL_KEY_PROVIDER_INVOKE_END_TIME_NANO, System.nanoTime());
}
return sofaResponse;
}
use of com.alipay.sofa.rpc.core.response.SofaResponse in project sofa-rpc by sofastack.
the class FaultToleranceSubscriberTest method onEvent.
@Test
public void onEvent() throws Exception {
ProviderInfo providerInfo = ProviderHelper.toProviderInfo("127.0.0.1");
FaultToleranceSubscriber subscriber = new FaultToleranceSubscriber();
subscriber.onEvent(new ClientSyncReceiveEvent(consumerConfig, providerInfo, new SofaRequest(), new SofaResponse(), null));
InvocationStat stat = InvocationStatFactory.getInvocationStat(consumerConfig, providerInfo);
Assert.assertNull(stat);
FaultToleranceConfig config = new FaultToleranceConfig();
config.setRegulationEffective(true);
FaultToleranceConfigManager.putAppConfig(APP_NAME1, config);
subscriber.onEvent(new ClientSyncReceiveEvent(consumerConfig, providerInfo, new SofaRequest(), new SofaResponse(), null));
stat = InvocationStatFactory.getInvocationStat(consumerConfig, providerInfo);
Assert.assertTrue(stat.getInvokeCount() == 1);
subscriber.onEvent(new ClientAsyncReceiveEvent(consumerConfig, providerInfo, new SofaRequest(), new SofaResponse(), null));
Assert.assertTrue(stat.getInvokeCount() == 2);
subscriber.onEvent(new ClientSyncReceiveEvent(consumerConfig, providerInfo, new SofaRequest(), null, new SofaTimeOutException("")));
Assert.assertTrue(stat.getExceptionCount() == 1);
subscriber.onEvent(new ClientAsyncReceiveEvent(consumerConfig, providerInfo, new SofaRequest(), null, new SofaTimeOutException("")));
Assert.assertTrue(stat.getExceptionCount() == 2);
Assert.assertTrue(stat.getExceptionRate() == 0.5d);
}
use of com.alipay.sofa.rpc.core.response.SofaResponse in project sofa-rpc by sofastack.
the class AbstractHttpClientHandler method receiveHttpResponse.
public void receiveHttpResponse(FullHttpResponse msg) {
HttpHeaders headers = msg.headers();
ByteBuf content = msg.content();
NettyByteBuffer data = new NettyByteBuffer(content);
try {
if (msg.status() == HttpResponseStatus.OK) {
// 正常返回
final SofaResponse response = new SofaResponse();
String isError = headers.get(RemotingConstants.HEAD_RESPONSE_ERROR);
if (CommonUtils.isTrue(isError)) {
// 业务异常
String errorMsg = StringSerializer.decode(data.array());
Throwable throwable = new SofaRpcException(RpcErrorType.SERVER_BIZ, errorMsg);
response.setAppResponse(throwable);
} else {
// 获取序列化类型
if (data.readableBytes() > 0) {
byte serializeType;
String codeName = headers.get(RemotingConstants.HEAD_SERIALIZE_TYPE);
if (codeName != null) {
serializeType = HttpTransportUtils.getSerializeTypeByName(codeName);
} else {
// HEAD_SERIALIZE_TYPE 没设置的话 再取 content-type 兜底下
String contentType = StringUtils.toString(headers.get(HttpHeaderNames.CONTENT_TYPE));
serializeType = HttpTransportUtils.getSerializeTypeByContentType(contentType);
}
response.setSerializeType(serializeType);
content.retain();
response.setData(data);
}
}
onResponse(response);
} else {
// 系统异常
String errorMsg = StringSerializer.decode(data.array());
Throwable throwable = new SofaRpcException(RpcErrorType.SERVER_UNDECLARED_ERROR, errorMsg);
onException(throwable);
}
} catch (final Exception e) {
onException(e);
}
}
use of com.alipay.sofa.rpc.core.response.SofaResponse in project sofa-rpc by sofastack.
the class HttpResponseFuture method releaseIfNeed.
@Override
protected void releaseIfNeed(Object result) {
if (result instanceof SofaResponse) {
AbstractByteBuf byteBuffer = response.getData();
if (byteBuffer != null) {
byteBuffer.release();
response.setData(null);
}
}
}
use of com.alipay.sofa.rpc.core.response.SofaResponse 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();
}
}
Aggregations