Search in sources :

Example 11 with SofaResponse

use of com.alipay.sofa.rpc.core.response.SofaResponse in project sofa-rpc by sofastack.

the class BoltServerProcessor method handleRequest.

@Override
public void handleRequest(BizContext bizCtx, AsyncContext asyncCtx, SofaRequest request) {
    // RPC内置上下文
    RpcInternalContext context = RpcInternalContext.getContext();
    context.setProviderSide(true);
    String appName = request.getTargetAppName();
    if (appName == null) {
        // 默认全局appName
        appName = (String) RpcRuntimeContext.get(RpcRuntimeContext.KEY_APPNAME);
    }
    // 是否链路异步化中
    boolean isAsyncChain = false;
    try {
        // 这个 try-finally 为了保证Context一定被清理
        // 统计值加1
        processingCount.incrementAndGet();
        // 远程地址
        context.setRemoteAddress(bizCtx.getRemoteHost(), bizCtx.getRemotePort());
        // 远程返回的通道
        context.setAttachment(RpcConstants.HIDDEN_KEY_ASYNC_CONTEXT, asyncCtx);
        InvokeContext boltInvokeCtx = bizCtx.getInvokeContext();
        if (RpcInternalContext.isAttachmentEnable()) {
            if (boltInvokeCtx != null) {
                // rpc线程池等待时间 Long
                putToContextIfNotNull(boltInvokeCtx, InvokeContext.BOLT_PROCESS_WAIT_TIME, context, RpcConstants.INTERNAL_KEY_PROCESS_WAIT_TIME);
            }
        }
        putToContext(boltInvokeCtx);
        if (EventBus.isEnable(ServerReceiveEvent.class)) {
            EventBus.post(new ServerReceiveEvent(request));
        }
        // 开始处理
        // 响应,用于返回
        SofaResponse response = null;
        // 异常,用于记录
        Throwable throwable = null;
        ProviderConfig providerConfig = null;
        String serviceName = request.getTargetServiceUniqueName();
        try {
            // 这个try-catch 保证一定有Response
            invoke: {
                if (!boltServer.isStarted()) {
                    // 服务端已关闭
                    throwable = new SofaRpcException(RpcErrorType.SERVER_CLOSED, LogCodes.getLog(LogCodes.WARN_PROVIDER_STOPPED, SystemInfo.getLocalHost() + ":" + boltServer.serverConfig.getPort()));
                    response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
                    break invoke;
                }
                if (bizCtx.isRequestTimeout()) {
                    // 加上丢弃超时的请求的逻辑
                    throwable = clientTimeoutWhenReceiveRequest(appName, serviceName, bizCtx.getRemoteAddress());
                    break invoke;
                }
                // 查找服务
                Invoker invoker = boltServer.findInvoker(serviceName);
                if (invoker == null) {
                    throwable = cannotFoundService(appName, serviceName);
                    response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
                    break invoke;
                }
                if (invoker instanceof ProviderProxyInvoker) {
                    providerConfig = ((ProviderProxyInvoker) invoker).getProviderConfig();
                    // 找到服务后,打印服务的appName
                    appName = providerConfig != null ? providerConfig.getAppName() : null;
                }
                // 查找方法
                String methodName = request.getMethodName();
                Method serviceMethod = ReflectCache.getOverloadMethodCache(serviceName, methodName, request.getMethodArgSigs());
                if (serviceMethod == null) {
                    throwable = cannotFoundServiceMethod(appName, methodName, serviceName);
                    response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
                    break invoke;
                } else {
                    request.setMethod(serviceMethod);
                }
                // 真正调用
                response = doInvoke(serviceName, invoker, request);
                if (bizCtx.isRequestTimeout()) {
                    // 加上丢弃超时的响应的逻辑
                    throwable = clientTimeoutWhenSendResponse(appName, serviceName, bizCtx.getRemoteAddress());
                    break invoke;
                }
            }
        } catch (Exception e) {
            // 服务端异常,不管是啥异常
            LOGGER.errorWithApp(appName, "Server Processor Error!", e);
            throwable = e;
            response = MessageBuilder.buildSofaErrorResponse(e.getMessage());
        }
        // Response不为空,代表需要返回给客户端
        if (response != null) {
            RpcInvokeContext invokeContext = RpcInvokeContext.peekContext();
            isAsyncChain = CommonUtils.isTrue(invokeContext != null ? (Boolean) invokeContext.remove(RemotingConstants.INVOKE_CTX_IS_ASYNC_CHAIN) : null);
            // 如果是服务端异步代理模式,特殊处理,因为该模式是在业务代码自主异步返回的
            if (!isAsyncChain) {
                // 其它正常请求
                try {
                    // 这个try-catch 保证一定要记录tracer
                    asyncCtx.sendResponse(response);
                } 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 {
        processingCount.decrementAndGet();
        if (!isAsyncChain) {
            if (EventBus.isEnable(ServerEndHandleEvent.class)) {
                EventBus.post(new ServerEndHandleEvent());
            }
        }
        RpcInvokeContext.removeContext();
        RpcInternalContext.removeAllContext();
    }
}
Also used : InvokeContext(com.alipay.remoting.InvokeContext) RpcInvokeContext(com.alipay.sofa.rpc.context.RpcInvokeContext) RpcInvokeContext(com.alipay.sofa.rpc.context.RpcInvokeContext) ServerSendEvent(com.alipay.sofa.rpc.event.ServerSendEvent) ProviderConfig(com.alipay.sofa.rpc.config.ProviderConfig) RpcInternalContext(com.alipay.sofa.rpc.context.RpcInternalContext) ServerEndHandleEvent(com.alipay.sofa.rpc.event.ServerEndHandleEvent) Method(java.lang.reflect.Method) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) 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)

Example 12 with SofaResponse

use of com.alipay.sofa.rpc.core.response.SofaResponse in project sofa-rpc by sofastack.

the class SofaRpcSerialization method serializeHeader.

@Override
public <Response extends ResponseCommand> boolean serializeHeader(Response response) throws SerializationException {
    if (response instanceof RpcResponseCommand) {
        RpcInternalContext.getContext().getStopWatch().tick();
        Object responseObject = ((RpcResponseCommand) response).getResponseObject();
        if (responseObject instanceof SofaResponse) {
            SofaResponse sofaResponse = (SofaResponse) responseObject;
            if (sofaResponse.isError() || sofaResponse.getAppResponse() instanceof Throwable) {
                sofaResponse.addResponseProp(RemotingConstants.HEAD_RESPONSE_ERROR, StringUtils.TRUE);
            }
            byte[] header = null;
            try {
                header = mapSerializer.encode(sofaResponse.getResponseProps());
            } catch (Exception e) {
                String traceId = (String) RpcInternalContext.getContext().getAttachment("_trace_id");
                String rpcId = (String) RpcInternalContext.getContext().getAttachment("_span_id");
                LOGGER.error("traceId={}, rpcId={}, Response serializeHeader exception, msg={}", traceId, rpcId, e.getMessage(), e);
                throw new SerializationException(e.getMessage() + ", traceId=" + traceId + ", rpcId=" + rpcId, e);
            }
            response.setHeader(header);
        }
        return true;
    }
    return false;
}
Also used : SerializationException(com.alipay.remoting.exception.SerializationException) RpcResponseCommand(com.alipay.remoting.rpc.protocol.RpcResponseCommand) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) DeserializationException(com.alipay.remoting.exception.DeserializationException) SerializationException(com.alipay.remoting.exception.SerializationException)

Example 13 with SofaResponse

use of com.alipay.sofa.rpc.core.response.SofaResponse in project sofa-rpc by sofastack.

the class ProviderBaggageFilter method invoke.

@Override
public SofaResponse invoke(FilterInvoker invoker, SofaRequest request) throws SofaRpcException {
    SofaResponse response = null;
    try {
        BaggageResolver.pickupFromRequest(RpcInvokeContext.peekContext(), request, true);
        response = invoker.invoke(request);
    } finally {
        if (response != null) {
            BaggageResolver.carryWithResponse(RpcInvokeContext.peekContext(), response);
        }
    }
    return response;
}
Also used : SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse)

Example 14 with SofaResponse

use of com.alipay.sofa.rpc.core.response.SofaResponse in project sofa-rpc by sofastack.

the class BoltClientTransport method syncSend.

@Override
public SofaResponse syncSend(SofaRequest request, int timeout) throws SofaRpcException {
    checkConnection();
    RpcInternalContext context = RpcInternalContext.getContext();
    InvokeContext boltInvokeContext = createInvokeContext(request);
    SofaResponse response = null;
    SofaRpcException throwable = null;
    try {
        beforeSend(context, request);
        response = doInvokeSync(request, boltInvokeContext, timeout);
        return response;
    } catch (Exception e) {
        // 其它异常
        throwable = convertToRpcException(e);
        throw throwable;
    } finally {
        afterSend(context, boltInvokeContext, request);
        if (EventBus.isEnable(ClientSyncReceiveEvent.class)) {
            EventBus.post(new ClientSyncReceiveEvent(transportConfig.getConsumerConfig(), transportConfig.getProviderInfo(), request, response, throwable));
        }
    }
}
Also used : InvokeContext(com.alipay.remoting.InvokeContext) RpcInvokeContext(com.alipay.sofa.rpc.context.RpcInvokeContext) RpcInternalContext(com.alipay.sofa.rpc.context.RpcInternalContext) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) ClientSyncReceiveEvent(com.alipay.sofa.rpc.event.ClientSyncReceiveEvent) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) InvokeServerException(com.alipay.remoting.rpc.exception.InvokeServerException) InvokeSendFailedException(com.alipay.remoting.rpc.exception.InvokeSendFailedException) SofaTimeOutException(com.alipay.sofa.rpc.core.exception.SofaTimeOutException) DeserializationException(com.alipay.remoting.exception.DeserializationException) InvokeTimeoutException(com.alipay.remoting.rpc.exception.InvokeTimeoutException) SerializationException(com.alipay.remoting.exception.SerializationException) RemotingException(com.alipay.remoting.exception.RemotingException) ConnectionClosedException(com.alipay.remoting.exception.ConnectionClosedException) InvokeServerBusyException(com.alipay.remoting.rpc.exception.InvokeServerBusyException) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) SofaRpcRuntimeException(com.alipay.sofa.rpc.core.exception.SofaRpcRuntimeException)

Example 15 with SofaResponse

use of com.alipay.sofa.rpc.core.response.SofaResponse in project sofa-rpc by sofastack.

the class SimpleMapSerializerTest method testParseResponseHeader.

@Test
public void testParseResponseHeader() {
    SofaRpcSerialization sofaRpcSerialization = new SofaRpcSerialization();
    Map<String, String> headerMap = new HashMap<>();
    headerMap.put("X-Tldc-Target-Tenant", "fia");
    SofaResponse sofaResponse = new SofaResponse();
    sofaRpcSerialization.parseResponseHeader(headerMap, sofaResponse);
    Assert.assertEquals("fia", sofaResponse.getResponseProps().get("X-Tldc-Target-Tenant"));
    sofaResponse.getResponseProps().clear();
    headerMap.put("exist", "");
    sofaResponse.addResponseProp("exist", "exist");
    sofaRpcSerialization.parseResponseHeader(headerMap, sofaResponse);
    Map<String, String> responseProps = sofaResponse.getResponseProps();
    Assert.assertEquals("fia", responseProps.get("X-Tldc-Target-Tenant"));
    Assert.assertEquals("exist", responseProps.get("exist"));
    sofaResponse.getResponseProps().clear();
    headerMap.put("X-Tldc-Target-Tenant", "fia");
    headerMap.put("exist", "");
    sofaRpcSerialization.parseResponseHeader(headerMap, sofaResponse);
    Assert.assertEquals("fia", responseProps.get("X-Tldc-Target-Tenant"));
    Assert.assertEquals("", responseProps.get("exist"));
}
Also used : HashMap(java.util.HashMap) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) Test(org.junit.Test)

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