public static void beforeSend(SofaRequest sofaRequest, ConsumerConfig consumerConfig, Metadata requestHeader) {

        // 客户端设置请求服务端的Header
        // tracer信息放入request 发到服务端

        Map<String, String> header = new HashMap<String, String>();
        header.put(RemotingConstants.HEAD_METHOD_NAME, sofaRequest.getMethodName());
        header.put(RemotingConstants.HEAD_TARGET_SERVICE, sofaRequest.getTargetServiceUniqueName());
        header.put(RemotingConstants.HEAD_TARGET_APP, sofaRequest.getTargetAppName());
        Map<String, Object> requestProps = sofaRequest.getRequestProps();
        if (requestProps != null) {
            CodecUtils.flatCopyTo("", requestProps, header);
        }
        //客户端的启动
        SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext();
        //获取并不弹出
        SofaTracerSpan clientSpan = sofaTraceContext.getCurrentSpan();
        if (clientSpan == null) {
            SelfLog.warn("ClientSpan is null.Before call interface=" + sofaRequest.getInterfaceName() + ",method=" +
                    sofaRequest.getMethodName());
        } else {
            SofaTracerSpanContext sofaTracerSpanContext = clientSpan.getSofaTracerSpanContext();
            header.put(TripleHeadKeys.HEAD_KEY_TRACE_ID.name(), sofaTracerSpanContext.getTraceId());
            header.put(TripleHeadKeys.HEAD_KEY_RPC_ID.name(), sofaTracerSpanContext.getSpanId());
            header.put(TripleHeadKeys.HEAD_KEY_OLD_TRACE_ID.name(), sofaTracerSpanContext.getTraceId());
            header.put(TripleHeadKeys.HEAD_KEY_OLD_RPC_ID.name(), sofaTracerSpanContext.getSpanId());

            header.put(TripleHeadKeys.HEAD_KEY_BIZ_BAGGAGE_TYPE.name(),
                    sofaTracerSpanContext.getBizSerializedBaggage());

            header.put(TripleHeadKeys.HEAD_KEY_SYS_BAGGAGE_TYPE.name(),
                    sofaTracerSpanContext.getSysSerializedBaggage());
        }
        //获取 RPC 上下文

        RpcInvokeContext internalContext = RpcInvokeContext.getContext();
        String route = (String) internalContext.get(USERID_KEY);

        if (StringUtils.isNotBlank(route)) {
            Map<String, String> map = new HashMap<>();
            map.put(USERID_KEY, route);
            header.put(TripleHeadKeys.HEAD_KEY_UNIT_INFO.name(), JSONUtils.toJSONString(map));
        }

        if (StringUtils.isNotEmpty(consumerConfig.getUniqueId())) {
            header.put(TripleHeadKeys.HEAD_KEY_SERVICE_VERSION.name(), consumerConfig.getUniqueId());
        }

        header.put(TripleHeadKeys.HEAD_KEY_META_TYPE.name(), "rpc");
        header.put(TripleHeadKeys.HEAD_KEY_CURRENT_APP.name(), (String) sofaRequest.getRequestProp(HEAD_APP_NAME));
        header.put(TripleHeadKeys.HEAD_KEY_CONSUMER_APP.name(), (String) sofaRequest.getRequestProp(HEAD_APP_NAME));

        header.put(TripleHeadKeys.HEAD_KEY_PROTOCOL_TYPE.name(),
                (String) sofaRequest.getRequestProp(RemotingConstants.HEAD_PROTOCOL));
        header.put(TripleHeadKeys.HEAD_KEY_INVOKE_TYPE.name(),
                (String) sofaRequest.getRequestProp(RemotingConstants.HEAD_INVOKE_TYPE));

        final String source = consumerConfig.getParameter("interworking.source");
        if (StringUtils.isNotBlank(source)) {
            header.put(TripleHeadKeys.HEAD_KEY_SOURCE_TENANTID.name(),
                    source);
        }

        final String target = consumerConfig.getParameter("interworking.target");
        if (StringUtils.isNotBlank(target)) {
            header.put(TripleHeadKeys.HEAD_KEY_TARGET_TENANTID.name(),
                    target);
        }
        for (Map.Entry<String, String> entry : header.entrySet()) {
            if (StringUtils.isNotBlank(entry.getValue())) {
                requestHeader.put(TripleHeadKeys.getKey(entry.getKey()), entry.getValue());
            }
        }

        // set custom headers
        try{
            Set<Map.Entry<String, String>> customHeader = RpcInvokeContext.getContext().getCustomHeader().entrySet();
            for (Map.Entry<String, String> entry : customHeader) {
                if (StringUtils.isNotBlank(entry.getValue())) {
                    requestHeader.put(TripleHeadKeys.getKey(entry.getKey()), entry.getValue());
                }
            }
        }finally {
            RpcInvokeContext.getContext().clearCustomHeader();
        }


    }
@Test
    public void testBeforeSend() {
        SofaRequest sofaRequest = new SofaRequest();
        sofaRequest.setTargetServiceUniqueName("targetService1");
        sofaRequest.addRequestProp("triple.header.key", "triple.header.value");
        Map map = new HashMap<String, String>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        sofaRequest.addRequestProp("triple.header.object", map);
        sofaRequest.addRequestProp(HEAD_TARGET_SERVICE, "targetService2");
        ConsumerConfig consumerConfig = new ConsumerConfig();
        Metadata metadata = new Metadata();
        TripleTracerAdapter.beforeSend(sofaRequest, consumerConfig, metadata);
        Assert.assertEquals("targetService2", metadata.get(TripleHeadKeys.getKey(HEAD_TARGET_SERVICE)));
        Assert.assertEquals("triple.header.value", metadata.get(TripleHeadKeys.getKey("triple.header.key")));
        Assert.assertEquals("value1", metadata.get(TripleHeadKeys.getKey("triple.header.object.key1")));
        Assert.assertEquals("value2", metadata.get(TripleHeadKeys.getKey("triple.header.object.key2")));
    }