Search in sources :

Example 66 with SofaResponse

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;
}
Also used : Method(java.lang.reflect.Method) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 67 with 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);
}
Also used : SofaRequest(com.alipay.sofa.rpc.core.request.SofaRequest) ProviderInfo(com.alipay.sofa.rpc.client.ProviderInfo) SofaTimeOutException(com.alipay.sofa.rpc.core.exception.SofaTimeOutException) ClientAsyncReceiveEvent(com.alipay.sofa.rpc.event.ClientAsyncReceiveEvent) FaultToleranceSubscriber(com.alipay.sofa.rpc.event.FaultToleranceSubscriber) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) ClientSyncReceiveEvent(com.alipay.sofa.rpc.event.ClientSyncReceiveEvent) Test(org.junit.Test)

Example 68 with SofaResponse

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);
    }
}
Also used : HttpHeaders(io.netty.handler.codec.http.HttpHeaders) ByteBuf(io.netty.buffer.ByteBuf) AbstractByteBuf(com.alipay.sofa.rpc.transport.AbstractByteBuf) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) NettyByteBuffer(com.alipay.sofa.rpc.transport.netty.NettyByteBuffer) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException)

Example 69 with SofaResponse

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);
        }
    }
}
Also used : AbstractByteBuf(com.alipay.sofa.rpc.transport.AbstractByteBuf) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse)

Example 70 with SofaResponse

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();
    }
}
Also used : AbstractByteBuf(com.alipay.sofa.rpc.transport.AbstractByteBuf) HashMap(java.util.HashMap) ServerSendEvent(com.alipay.sofa.rpc.event.ServerSendEvent) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) ProviderConfig(com.alipay.sofa.rpc.config.ProviderConfig) RpcInternalContext(com.alipay.sofa.rpc.context.RpcInternalContext) Channel(io.netty.channel.Channel) ServerEndHandleEvent(com.alipay.sofa.rpc.event.ServerEndHandleEvent) Method(java.lang.reflect.Method) ByteBuf(io.netty.buffer.ByteBuf) AbstractByteBuf(com.alipay.sofa.rpc.transport.AbstractByteBuf) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) ProviderProxyInvoker(com.alipay.sofa.rpc.server.ProviderProxyInvoker) Invoker(com.alipay.sofa.rpc.invoke.Invoker) ProviderProxyInvoker(com.alipay.sofa.rpc.server.ProviderProxyInvoker) ServerReceiveEvent(com.alipay.sofa.rpc.event.ServerReceiveEvent) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) StringSerializer(com.alipay.sofa.rpc.codec.common.StringSerializer) Serializer(com.alipay.sofa.rpc.codec.Serializer)

Aggregations

SofaResponse (com.alipay.sofa.rpc.core.response.SofaResponse)85 SofaRpcException (com.alipay.sofa.rpc.core.exception.SofaRpcException)25 Test (org.junit.Test)21 SofaRequest (com.alipay.sofa.rpc.core.request.SofaRequest)19 RpcInternalContext (com.alipay.sofa.rpc.context.RpcInternalContext)12 Method (java.lang.reflect.Method)10 AbstractByteBuf (com.alipay.sofa.rpc.transport.AbstractByteBuf)9 HashMap (java.util.HashMap)9 ProviderConfig (com.alipay.sofa.rpc.config.ProviderConfig)6 ClientEndInvokeEvent (com.alipay.sofa.rpc.event.ClientEndInvokeEvent)6 ByteArrayWrapperByteBuf (com.alipay.sofa.rpc.transport.ByteArrayWrapperByteBuf)6 ProviderInfo (com.alipay.sofa.rpc.client.ProviderInfo)5 ClientAsyncReceiveEvent (com.alipay.sofa.rpc.event.ClientAsyncReceiveEvent)5 ClientSyncReceiveEvent (com.alipay.sofa.rpc.event.ClientSyncReceiveEvent)5 Serializer (com.alipay.sofa.rpc.codec.Serializer)4 ConsumerConfig (com.alipay.sofa.rpc.config.ConsumerConfig)4 FilterChain (com.alipay.sofa.rpc.filter.FilterChain)4 Hessian2Input (com.caucho.hessian.io.Hessian2Input)4 BlockException (com.alibaba.csp.sentinel.slots.block.BlockException)3 DeserializationException (com.alipay.remoting.exception.DeserializationException)3