@Override
    public DefaultAuthenticationContext build(Metadata metadata, GeneratedMessageV3 request) {
        try {
            DefaultAuthenticationContext context = new DefaultAuthenticationContext();
            context.setChannelId(metadata.get(GrpcConstants.CHANNEL_ID));
            context.setRpcCode(request.getDescriptorForType().getFullName());
            String authorization = metadata.get(GrpcConstants.AUTHORIZATION);
            if (StringUtils.isEmpty(authorization)) {
                return context;
            }
            String datetime = metadata.get(GrpcConstants.DATE_TIME);
            if (StringUtils.isEmpty(datetime)) {
                throw new AuthenticationException("datetime is null.");
            }

            String[] result = authorization.split(CommonConstants.SPACE, 2);
            if (result.length != 2) {
                throw new AuthenticationException("authentication header is incorrect.");
            }
            String[] keyValues = result[1].split(CommonConstants.COMMA);
            for (String keyValue : keyValues) {
                String[] kv = keyValue.trim().split(CommonConstants.EQUAL, 2);
                int kvLength = kv.length;
                if (kv.length != 2) {
                    throw new AuthenticationException("authentication keyValues length is incorrect, actual length={}.", kvLength);
                }
                String authItem = kv[0];
                if (CREDENTIAL.equals(authItem)) {
                    String[] credential = kv[1].split(CommonConstants.SLASH);
                    int credentialActualLength = credential.length;
                    if (credentialActualLength == 0) {
                        throw new AuthenticationException("authentication credential length is incorrect, actual length={}.", credentialActualLength);
                    }
                    context.setUsername(credential[0]);
                    continue;
                }
                if (SIGNATURE.equals(authItem)) {
                    context.setSignature(this.hexToBase64(kv[1]));
                }
            }

            context.setContent(datetime.getBytes(StandardCharsets.UTF_8));

            return context;
        } catch (AuthenticationException e) {
            throw e;
        } catch (Throwable e) {
            throw new AuthenticationException("create authentication context error.", e);
        }
    }
@Test
    public void build2() {
        when(channel.id()).thenReturn(mockChannelId("channel-id"));
        when(channelHandlerContext.channel()).thenReturn(channel);
        SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
        requestHeader.setTopic("topic-test");
        requestHeader.setQueueId(0);
        requestHeader.setBornTimestamp(117036786441330L);
        requestHeader.setBname("brokerName-1");
        RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.SEND_MESSAGE, requestHeader);
        request.setVersion(441);
        request.addExtField("AccessKey", "abc");
        request.addExtField("Signature", "ZG26exJ5u9q1fwZlO4DCmz2Rs88=");
        request.makeCustomHeaderToNet();
        DefaultAuthenticationContext context = builder.build(channelHandlerContext, request);
        Assert.assertNotNull(context);
        Assert.assertEquals("abc", context.getUsername());
        Assert.assertEquals("ZG26exJ5u9q1fwZlO4DCmz2Rs88=", context.getSignature());
        Assert.assertEquals("abcbrokerName-11170367864413300topic-test", new String(context.getContent(), StandardCharsets.UTF_8));
    }