@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 build1() {
        Resource topic = Resource.newBuilder().setName("topic-test").build();
        {
            SendMessageRequest request = SendMessageRequest.newBuilder()
                .addMessages(Message.newBuilder().setTopic(topic)
                    .setBody(ByteString.copyFromUtf8("message-body"))
                    .build())
                .build();
            Metadata metadata = new Metadata();
            metadata.put(GrpcConstants.AUTHORIZATION, "MQv2-HMAC-SHA1 Credential=abc, SignedHeaders=x-mq-date-time, Signature=D18A9CBCDDBA9041D6693268FEF15A989E64430B");
            metadata.put(GrpcConstants.DATE_TIME, "20231227T194619Z");
            DefaultAuthenticationContext context = builder.build(metadata, request);
            Assert.assertNotNull(context);
            Assert.assertEquals("abc", context.getUsername());
            Assert.assertEquals("0YqcvN26kEHWaTJo/vFamJ5kQws=", context.getSignature());
            Assert.assertEquals("20231227T194619Z", new String(context.getContent(), StandardCharsets.UTF_8));
        }
    }