@Override
    public List<DefaultAuthorizationContext> build(Metadata metadata, GeneratedMessageV3 message) {
        List<DefaultAuthorizationContext> result = null;
        if (message instanceof SendMessageRequest) {
            SendMessageRequest request = (SendMessageRequest) message;
            if (request.getMessagesCount() <= 0) {
                throw new AuthorizationException("message is null.");
            }
            result = newPubContext(metadata, request.getMessages(0).getTopic());
        }
        if (message instanceof EndTransactionRequest) {
            EndTransactionRequest request = (EndTransactionRequest) message;
            result = newPubContext(metadata, request.getTopic());
        }
        if (message instanceof HeartbeatRequest) {
            HeartbeatRequest request = (HeartbeatRequest) message;
            if (!isConsumerClientType(request.getClientType())) {
                return null;
            }
            result = newGroupSubContexts(metadata, request.getGroup());
        }
        if (message instanceof ReceiveMessageRequest) {
            ReceiveMessageRequest request = (ReceiveMessageRequest) message;
            if (!request.hasMessageQueue()) {
                throw new AuthorizationException("messageQueue is null.");
            }
            result = newSubContexts(metadata, request.getGroup(), request.getMessageQueue().getTopic());
        }
        if (message instanceof AckMessageRequest) {
            AckMessageRequest request = (AckMessageRequest) message;
            result = newSubContexts(metadata, request.getGroup(), request.getTopic());
        }
        if (message instanceof ForwardMessageToDeadLetterQueueRequest) {
            ForwardMessageToDeadLetterQueueRequest request = (ForwardMessageToDeadLetterQueueRequest) message;
            result = newSubContexts(metadata, request.getGroup(), request.getTopic());
        }
        if (message instanceof NotifyClientTerminationRequest) {
            NotifyClientTerminationRequest request = (NotifyClientTerminationRequest) message;
            if (StringUtils.isNotBlank(request.getGroup().getName())) {
                result = newGroupSubContexts(metadata, request.getGroup());
            }
        }
        if (message instanceof ChangeInvisibleDurationRequest) {
            ChangeInvisibleDurationRequest request = (ChangeInvisibleDurationRequest) message;
            result = newGroupSubContexts(metadata, request.getGroup());
        }
        if (message instanceof QueryRouteRequest) {
            QueryRouteRequest request = (QueryRouteRequest) message;
            result = newContext(metadata, request);
        }
        if (message instanceof QueryAssignmentRequest) {
            QueryAssignmentRequest request = (QueryAssignmentRequest) message;
            result = newSubContexts(metadata, request.getGroup(), request.getTopic());
        }
        if (message instanceof TelemetryCommand) {
            TelemetryCommand request = (TelemetryCommand) message;
            result = newContext(metadata, request);
        }
        if (CollectionUtils.isNotEmpty(result)) {
            result.forEach(context -> {
                context.setChannelId(metadata.get(GrpcConstants.CHANNEL_ID));
                context.setRpcCode(message.getDescriptorForType().getFullName());
            });
        }
        return result;
    }
@Test
    public void buildGrpc() {
        Metadata metadata = new Metadata();
        metadata.put(GrpcConstants.AUTHORIZATION_AK, "rocketmq");
        metadata.put(GrpcConstants.REMOTE_ADDRESS, "192.168.0.1");
        metadata.put(GrpcConstants.CHANNEL_ID, "channel-id");

        GeneratedMessageV3 request = SendMessageRequest.newBuilder()
            .addMessages(Message.newBuilder()
                .setTopic(Resource.newBuilder().setName("topic").build())
                .build())
            .build();
        List<DefaultAuthorizationContext> result = builder.build(metadata, request);
        Assert.assertEquals(1, result.size());
        Assert.assertEquals(result.get(0).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(result.get(0).getResource().getResourceKey(), "Topic:topic");
        Assert.assertTrue(result.get(0).getActions().containsAll(Arrays.asList(Action.PUB)));
        Assert.assertEquals(result.get(0).getSourceIp(), "192.168.0.1");
        Assert.assertEquals(result.get(0).getChannelId(), "channel-id");
        Assert.assertEquals(result.get(0).getRpcCode(), SendMessageRequest.getDescriptor().getFullName());

        request = EndTransactionRequest.newBuilder()
            .setTopic(Resource.newBuilder().setName("topic").build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(1, result.size());
        Assert.assertEquals(result.get(0).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(result.get(0).getResource().getResourceKey(), "Topic:topic");
        Assert.assertTrue(result.get(0).getActions().containsAll(Arrays.asList(Action.PUB)));

        request = HeartbeatRequest.newBuilder()
            .setClientType(ClientType.PUSH_CONSUMER)
            .setGroup(Resource.newBuilder().setName("group").build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(1, result.size());
        Assert.assertEquals(result.get(0).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(result.get(0).getResource().getResourceKey(), "Group:group");
        Assert.assertTrue(result.get(0).getActions().containsAll(Arrays.asList(Action.SUB)));

        request = ReceiveMessageRequest.newBuilder()
            .setMessageQueue(MessageQueue.newBuilder()
                .setTopic(Resource.newBuilder().setName("topic").build())
                .build())
            .setGroup(Resource.newBuilder().setName("group").build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(2, result.size());
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getResource().getResourceKey(), "Group:group");
        Assert.assertTrue(getContext(result, ResourceType.GROUP).getActions().containsAll(Arrays.asList(Action.SUB)));
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getResource().getResourceKey(), "Topic:topic");
        Assert.assertTrue(getContext(result, ResourceType.TOPIC).getActions().containsAll(Arrays.asList(Action.SUB)));

        request = AckMessageRequest.newBuilder()
            .setTopic(Resource.newBuilder().setName("topic").build())
            .setGroup(Resource.newBuilder().setName("group").build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(2, result.size());
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getResource().getResourceKey(), "Group:group");
        Assert.assertTrue(getContext(result, ResourceType.GROUP).getActions().containsAll(Arrays.asList(Action.SUB)));
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getResource().getResourceKey(), "Topic:topic");
        Assert.assertTrue(getContext(result, ResourceType.TOPIC).getActions().containsAll(Arrays.asList(Action.SUB)));

        request = ForwardMessageToDeadLetterQueueRequest.newBuilder()
            .setTopic(Resource.newBuilder().setName("topic").build())
            .setGroup(Resource.newBuilder().setName("group").build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(2, result.size());
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getResource().getResourceKey(), "Group:group");
        Assert.assertTrue(getContext(result, ResourceType.GROUP).getActions().containsAll(Arrays.asList(Action.SUB)));
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getResource().getResourceKey(), "Topic:topic");
        Assert.assertTrue(getContext(result, ResourceType.TOPIC).getActions().containsAll(Arrays.asList(Action.SUB)));

        request = NotifyClientTerminationRequest.newBuilder()
            .setGroup(Resource.newBuilder().setName("group").build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(1, result.size());
        Assert.assertEquals(result.get(0).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(result.get(0).getResource().getResourceKey(), "Group:group");
        Assert.assertTrue(result.get(0).getActions().containsAll(Arrays.asList(Action.SUB)));

        request = ChangeInvisibleDurationRequest.newBuilder()
            .setGroup(Resource.newBuilder().setName("group").build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(1, result.size());
        Assert.assertEquals(result.get(0).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(result.get(0).getResource().getResourceKey(), "Group:group");
        Assert.assertTrue(result.get(0).getActions().containsAll(Arrays.asList(Action.SUB)));

        request = QueryRouteRequest.newBuilder()
            .setTopic(Resource.newBuilder().setName("topic").build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(1, result.size());
        Assert.assertEquals(result.get(0).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(result.get(0).getResource().getResourceKey(), "Topic:topic");
        Assert.assertTrue(result.get(0).getActions().containsAll(Arrays.asList(Action.PUB, Action.SUB)));

        request = QueryAssignmentRequest.newBuilder()
            .setTopic(Resource.newBuilder().setName("topic").build())
            .setGroup(Resource.newBuilder().setName("group").build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(2, result.size());
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getResource().getResourceKey(), "Group:group");
        Assert.assertTrue(getContext(result, ResourceType.GROUP).getActions().containsAll(Arrays.asList(Action.SUB)));
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getResource().getResourceKey(), "Topic:topic");
        Assert.assertTrue(getContext(result, ResourceType.TOPIC).getActions().containsAll(Arrays.asList(Action.SUB)));

        request = TelemetryCommand.newBuilder()
            .setSettings(Settings.newBuilder()
                .setPublishing(Publishing.newBuilder()
                    .addTopics(Resource.newBuilder().setName("topic").build())
                    .build())
                .build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(1, result.size());
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getResource().getResourceKey(), "Topic:topic");
        Assert.assertTrue(getContext(result, ResourceType.TOPIC).getActions().containsAll(Arrays.asList(Action.PUB)));

        request = TelemetryCommand.newBuilder()
            .setSettings(Settings.newBuilder()
                .setSubscription(Subscription.newBuilder()
                    .setGroup(Resource.newBuilder().setName("group").build())
                    .addSubscriptions(SubscriptionEntry.newBuilder()
                        .setTopic(Resource.newBuilder().setName("topic").build())
                        .build())
                    .build())
                .build())
            .build();
        result = builder.build(metadata, request);
        Assert.assertEquals(2, result.size());
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.GROUP).getResource().getResourceKey(), "Group:group");
        Assert.assertTrue(getContext(result, ResourceType.GROUP).getActions().containsAll(Arrays.asList(Action.SUB)));
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getSubject().getSubjectKey(), "User:rocketmq");
        Assert.assertEquals(getContext(result, ResourceType.TOPIC).getResource().getResourceKey(), "Topic:topic");
        Assert.assertTrue(getContext(result, ResourceType.TOPIC).getActions().containsAll(Arrays.asList(Action.SUB)));
    }