Search in sources :

Example 6 with Serializer

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();
        }
    }
}
Also used : AbstractByteBuf(com.alipay.sofa.rpc.transport.AbstractByteBuf) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) TimerTask(io.netty.util.TimerTask) Timeout(io.netty.util.Timeout) ClientHandler(com.alipay.sofa.rpc.transport.ClientHandler) TimeoutException(java.util.concurrent.TimeoutException) SofaTimeOutException(com.alipay.sofa.rpc.core.exception.SofaTimeOutException) ExecutionException(java.util.concurrent.ExecutionException) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) Serializer(com.alipay.sofa.rpc.codec.Serializer)

Example 7 with Serializer

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();
    }
}
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)

Example 8 with Serializer

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;
}
Also used : SofaRequest(com.alipay.sofa.rpc.core.request.SofaRequest) ByteArrayWrapperByteBuf(com.alipay.sofa.rpc.transport.ByteArrayWrapperByteBuf) DeserializationException(com.alipay.remoting.exception.DeserializationException) DeserializationException(com.alipay.remoting.exception.DeserializationException) SerializationException(com.alipay.remoting.exception.SerializationException) HashMap(java.util.HashMap) Map(java.util.Map) RpcRequestCommand(com.alipay.remoting.rpc.protocol.RpcRequestCommand) Serializer(com.alipay.sofa.rpc.codec.Serializer) DefaultCustomSerializer(com.alipay.remoting.DefaultCustomSerializer)

Example 9 with Serializer

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;
}
Also used : ByteArrayWrapperByteBuf(com.alipay.sofa.rpc.transport.ByteArrayWrapperByteBuf) DeserializationException(com.alipay.remoting.exception.DeserializationException) SerializationException(com.alipay.remoting.exception.SerializationException) DeserializationException(com.alipay.remoting.exception.DeserializationException) RpcResponseCommand(com.alipay.remoting.rpc.protocol.RpcResponseCommand) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) HashMap(java.util.HashMap) Map(java.util.Map) Serializer(com.alipay.sofa.rpc.codec.Serializer) DefaultCustomSerializer(com.alipay.remoting.DefaultCustomSerializer)

Example 10 with Serializer

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);
    }
}
Also used : SofaRequest(com.alipay.sofa.rpc.core.request.SofaRequest) ByteString(com.google.protobuf.ByteString) Method(java.lang.reflect.Method) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) SofaRpcRuntimeException(com.alipay.sofa.rpc.core.exception.SofaRpcRuntimeException) Response(triple.Response) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) SofaRpcRuntimeException(com.alipay.sofa.rpc.core.exception.SofaRpcRuntimeException) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) Serializer(com.alipay.sofa.rpc.codec.Serializer)

Aggregations

Serializer (com.alipay.sofa.rpc.codec.Serializer)10 AbstractByteBuf (com.alipay.sofa.rpc.transport.AbstractByteBuf)5 HashMap (java.util.HashMap)5 DefaultCustomSerializer (com.alipay.remoting.DefaultCustomSerializer)4 DeserializationException (com.alipay.remoting.exception.DeserializationException)4 SerializationException (com.alipay.remoting.exception.SerializationException)4 SofaRpcException (com.alipay.sofa.rpc.core.exception.SofaRpcException)4 SofaResponse (com.alipay.sofa.rpc.core.response.SofaResponse)4 ByteArrayWrapperByteBuf (com.alipay.sofa.rpc.transport.ByteArrayWrapperByteBuf)4 SofaRequest (com.alipay.sofa.rpc.core.request.SofaRequest)3 Method (java.lang.reflect.Method)3 Map (java.util.Map)3 Response (triple.Response)3 RpcRequestCommand (com.alipay.remoting.rpc.protocol.RpcRequestCommand)2 RpcResponseCommand (com.alipay.remoting.rpc.protocol.RpcResponseCommand)2 StringSerializer (com.alipay.sofa.rpc.codec.common.StringSerializer)2 ByteString (com.google.protobuf.ByteString)2 SofaHessianSerializer (com.alipay.sofa.rpc.codec.sofahessian.SofaHessianSerializer)1 ProviderConfig (com.alipay.sofa.rpc.config.ProviderConfig)1 RpcInternalContext (com.alipay.sofa.rpc.context.RpcInternalContext)1