|
23 | 23 | import java.util.ArrayList; |
24 | 24 | import java.util.Arrays; |
25 | 25 | import java.util.List; |
| 26 | +import java.util.Map; |
| 27 | +import java.util.Objects; |
| 28 | +import java.util.Optional; |
26 | 29 | import java.util.Set; |
27 | 30 | import java.util.concurrent.ArrayBlockingQueue; |
28 | 31 | import java.util.concurrent.CompletableFuture; |
| 32 | +import java.util.concurrent.ConcurrentHashMap; |
| 33 | +import java.util.concurrent.ConcurrentMap; |
29 | 34 | import java.util.concurrent.CopyOnWriteArrayList; |
30 | 35 | import java.util.concurrent.CountDownLatch; |
31 | 36 | import java.util.concurrent.ExecutorService; |
|
102 | 107 | import org.apache.rocketmq.remoting.protocol.body.UnlockBatchRequestBody; |
103 | 108 | import org.apache.rocketmq.remoting.protocol.header.ExchangeHAInfoRequestHeader; |
104 | 109 | import org.apache.rocketmq.remoting.protocol.header.ExchangeHAInfoResponseHeader; |
| 110 | +import org.apache.rocketmq.remoting.protocol.header.GetAllSubscriptionGroupRequestHeader; |
| 111 | +import org.apache.rocketmq.remoting.protocol.header.GetAllSubscriptionGroupResponseHeader; |
| 112 | +import org.apache.rocketmq.remoting.protocol.header.GetAllTopicConfigRequestHeader; |
| 113 | +import org.apache.rocketmq.remoting.protocol.header.GetAllTopicConfigResponseHeader; |
105 | 114 | import org.apache.rocketmq.remoting.protocol.header.GetBrokerMemberGroupRequestHeader; |
106 | 115 | import org.apache.rocketmq.remoting.protocol.header.GetMaxOffsetRequestHeader; |
107 | 116 | import org.apache.rocketmq.remoting.protocol.header.GetMaxOffsetResponseHeader; |
|
139 | 148 | import org.apache.rocketmq.remoting.protocol.route.BrokerData; |
140 | 149 | import org.apache.rocketmq.remoting.protocol.route.QueueData; |
141 | 150 | import org.apache.rocketmq.remoting.protocol.route.TopicRouteData; |
| 151 | +import org.apache.rocketmq.remoting.protocol.statictopic.TopicQueueMappingDetail; |
| 152 | +import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig; |
142 | 153 | import org.apache.rocketmq.remoting.rpc.ClientMetadata; |
143 | 154 | import org.apache.rocketmq.remoting.rpc.RpcClient; |
144 | 155 | import org.apache.rocketmq.remoting.rpc.RpcClientImpl; |
@@ -761,22 +772,78 @@ public void run0() { |
761 | 772 | return changedList; |
762 | 773 | } |
763 | 774 |
|
764 | | - public TopicConfigAndMappingSerializeWrapper getAllTopicConfig( |
765 | | - final String addr) throws RemotingConnectException, RemotingSendRequestException, |
766 | | - RemotingTimeoutException, InterruptedException, MQBrokerException { |
767 | | - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_ALL_TOPIC_CONFIG, null); |
| 775 | + public TopicConfigAndMappingSerializeWrapper getAllTopicConfig(final String addr) |
| 776 | + throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, |
| 777 | + InterruptedException, MQBrokerException, RemotingCommandException { |
| 778 | + |
| 779 | + DataVersion topicConfigDataVersion = null; |
| 780 | + DataVersion mappingDataVersion = null; |
| 781 | + int topicSeq = 0; |
| 782 | + ConcurrentHashMap<String, TopicConfig> topicConfigTable = new ConcurrentHashMap<>(); |
| 783 | + Map<String, TopicQueueMappingDetail> topicQueueMappingDetailMap = new ConcurrentHashMap<>(); |
| 784 | + while (true) { |
| 785 | + GetAllTopicConfigRequestHeader requestHeader = new GetAllTopicConfigRequestHeader(); |
| 786 | + requestHeader.setTopicSeq(topicSeq); |
| 787 | + requestHeader.setMaxTopicNum(2000); |
| 788 | + requestHeader.setDataVersion(Optional.ofNullable(topicConfigDataVersion). |
| 789 | + map(DataVersion::toJson).orElse(StringUtils.EMPTY)); |
| 790 | + |
| 791 | + RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_ALL_TOPIC_CONFIG, requestHeader); |
| 792 | + |
| 793 | + RemotingCommand response = this.remotingClient.invokeSync( |
| 794 | + MixAll.brokerVIPChannel(true, addr), request, 3000); |
| 795 | + |
| 796 | + assert response != null; |
| 797 | + if (response.getCode() == SUCCESS) { |
| 798 | + TopicConfigAndMappingSerializeWrapper topicConfigSerializeWrapper = |
| 799 | + TopicConfigAndMappingSerializeWrapper.decode(response.getBody(), TopicConfigAndMappingSerializeWrapper.class); |
| 800 | + topicConfigTable.putAll(topicConfigSerializeWrapper.getTopicConfigTable()); |
| 801 | + topicQueueMappingDetailMap.putAll(topicConfigSerializeWrapper.getTopicQueueMappingDetailMap()); |
| 802 | + topicSeq += topicConfigSerializeWrapper.getTopicConfigTable().size(); |
| 803 | + |
| 804 | + |
| 805 | + DataVersion newDataVersion = topicConfigSerializeWrapper.getDataVersion(); |
| 806 | + if (topicConfigDataVersion == null) { |
| 807 | + // fill dataVersion before break the loop to compatible with old version server |
| 808 | + topicConfigDataVersion = newDataVersion; |
| 809 | + mappingDataVersion = topicConfigSerializeWrapper.getMappingDataVersion(); |
| 810 | + } |
768 | 811 |
|
769 | | - RemotingCommand response = this.remotingClient.invokeSync(MixAll.brokerVIPChannel(true, addr), request, 3000); |
770 | | - assert response != null; |
771 | | - switch (response.getCode()) { |
772 | | - case ResponseCode.SUCCESS: { |
773 | | - return TopicConfigSerializeWrapper.decode(response.getBody(), TopicConfigAndMappingSerializeWrapper.class); |
| 812 | + GetAllTopicConfigResponseHeader responseHeader = |
| 813 | + response.decodeCommandCustomHeader(GetAllTopicConfigResponseHeader.class); |
| 814 | + Integer totalTopicNum = Optional.ofNullable(responseHeader) |
| 815 | + .map(GetAllTopicConfigResponseHeader::getTotalTopicNum).orElse(null); |
| 816 | + |
| 817 | + if (Objects.isNull(totalTopicNum)) { // compatible with old version server |
| 818 | + // the server side don't support totalTopicNum, all data is returned |
| 819 | + break; |
| 820 | + } |
| 821 | + |
| 822 | + if (!Objects.equals(topicConfigDataVersion, newDataVersion)) { |
| 823 | + LOGGER.error("dataVersion changed, currentDataVersion: {}, newDataVersion: {}", topicConfigDataVersion, newDataVersion); |
| 824 | + topicConfigDataVersion = newDataVersion; |
| 825 | + mappingDataVersion = topicConfigSerializeWrapper.getMappingDataVersion(); |
| 826 | + topicSeq = 0; |
| 827 | + topicConfigTable.clear(); |
| 828 | + continue; |
| 829 | + } |
| 830 | + |
| 831 | + if (topicSeq >= totalTopicNum - 1) { |
| 832 | + LOGGER.info("get all topic config, totalTopicNum: {}", totalTopicNum); |
| 833 | + break; |
| 834 | + } |
| 835 | + } else { |
| 836 | + throw new MQBrokerException(response.getCode(), response.getRemark(), addr); |
774 | 837 | } |
775 | | - default: |
776 | | - break; |
| 838 | + |
777 | 839 | } |
778 | 840 |
|
779 | | - throw new MQBrokerException(response.getCode(), response.getRemark(), addr); |
| 841 | + TopicConfigAndMappingSerializeWrapper topicConfigSerializeWrapper = new TopicConfigAndMappingSerializeWrapper(); |
| 842 | + topicConfigSerializeWrapper.setDataVersion(topicConfigDataVersion); |
| 843 | + topicConfigSerializeWrapper.setTopicConfigTable(topicConfigTable); |
| 844 | + topicConfigSerializeWrapper.setMappingDataVersion(mappingDataVersion); |
| 845 | + topicConfigSerializeWrapper.setTopicQueueMappingDetailMap(topicQueueMappingDetailMap); |
| 846 | + return topicConfigSerializeWrapper; |
780 | 847 | } |
781 | 848 |
|
782 | 849 | public TimerCheckpoint getTimerCheckPoint( |
@@ -849,21 +916,73 @@ public String getAllDelayOffset( |
849 | 916 | throw new MQBrokerException(response.getCode(), response.getRemark(), addr); |
850 | 917 | } |
851 | 918 |
|
852 | | - public SubscriptionGroupWrapper getAllSubscriptionGroupConfig( |
853 | | - final String addr) throws InterruptedException, RemotingTimeoutException, |
854 | | - RemotingSendRequestException, RemotingConnectException, MQBrokerException { |
855 | | - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_ALL_SUBSCRIPTIONGROUP_CONFIG, null); |
856 | | - RemotingCommand response = this.remotingClient.invokeSync(addr, request, 3000); |
857 | | - assert response != null; |
858 | | - switch (response.getCode()) { |
859 | | - case ResponseCode.SUCCESS: { |
860 | | - return SubscriptionGroupWrapper.decode(response.getBody(), SubscriptionGroupWrapper.class); |
| 919 | + public SubscriptionGroupWrapper getAllSubscriptionGroupConfig(final String addr) |
| 920 | + throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, |
| 921 | + RemotingConnectException, MQBrokerException, RemotingCommandException { |
| 922 | + DataVersion currentDataVersion = null; |
| 923 | + int groupSeq = 0; |
| 924 | + ConcurrentMap<String, SubscriptionGroupConfig> subscriptionGroupTable = new ConcurrentHashMap<>(); |
| 925 | + ConcurrentMap<String, ConcurrentMap<String, Integer>> forbiddenTable = new ConcurrentHashMap<>(); |
| 926 | + while (true) { |
| 927 | + |
| 928 | + GetAllSubscriptionGroupRequestHeader requestHeader = new GetAllSubscriptionGroupRequestHeader(); |
| 929 | + requestHeader.setGroupSeq(groupSeq); |
| 930 | + requestHeader.setMaxGroupNum(2000); |
| 931 | + requestHeader.setDataVersion(Optional.ofNullable(currentDataVersion) |
| 932 | + .map(DataVersion::toJson).orElse(StringUtils.EMPTY)); |
| 933 | + |
| 934 | + RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_ALL_SUBSCRIPTIONGROUP_CONFIG, requestHeader); |
| 935 | + RemotingCommand response = this.remotingClient.invokeSync(addr, request, 3000); |
| 936 | + |
| 937 | + assert response != null; |
| 938 | + if (response.getCode() == SUCCESS) { |
| 939 | + SubscriptionGroupWrapper subscriptionGroupWrapper = |
| 940 | + SubscriptionGroupWrapper.decode(response.getBody(), SubscriptionGroupWrapper.class); |
| 941 | + subscriptionGroupTable.putAll(subscriptionGroupWrapper.getSubscriptionGroupTable()); |
| 942 | + forbiddenTable.putAll(subscriptionGroupWrapper.getForbiddenTable()); |
| 943 | + |
| 944 | + DataVersion newDataVersion = subscriptionGroupWrapper.getDataVersion(); |
| 945 | + if (currentDataVersion == null) { |
| 946 | + // fill dataVersion before break the loop to compatible with old version server |
| 947 | + currentDataVersion = newDataVersion; |
| 948 | + } |
| 949 | + |
| 950 | + groupSeq += subscriptionGroupWrapper.getSubscriptionGroupTable().size(); |
| 951 | + |
| 952 | + GetAllSubscriptionGroupResponseHeader responseHeader = |
| 953 | + response.decodeCommandCustomHeader(GetAllSubscriptionGroupResponseHeader.class); |
| 954 | + Integer totalGroupNum = Optional.ofNullable(responseHeader) |
| 955 | + .map(GetAllSubscriptionGroupResponseHeader::getTotalGroupNum).orElse(null); |
| 956 | + |
| 957 | + if (Objects.isNull(totalGroupNum)) { |
| 958 | + // the server side don't support totalGroupNum, all data is returned |
| 959 | + break; |
| 960 | + } |
| 961 | + |
| 962 | + if (!Objects.equals(currentDataVersion, newDataVersion)) { |
| 963 | + LOGGER.error("dataVersion changed, currentDataVersion: {}, newDataVersion: {}", |
| 964 | + currentDataVersion, newDataVersion); |
| 965 | + currentDataVersion = newDataVersion; |
| 966 | + groupSeq = 0; |
| 967 | + subscriptionGroupTable.clear(); |
| 968 | + forbiddenTable.clear(); |
| 969 | + continue; |
| 970 | + } |
| 971 | + |
| 972 | + if (groupSeq >= totalGroupNum - 1) { |
| 973 | + LOGGER.info("get all subscription group config, totalGroupNum: {}", totalGroupNum); |
| 974 | + break; |
| 975 | + } |
| 976 | + } else { |
| 977 | + throw new MQBrokerException(response.getCode(), response.getRemark(), addr); |
861 | 978 | } |
862 | | - default: |
863 | | - break; |
864 | 979 | } |
865 | 980 |
|
866 | | - throw new MQBrokerException(response.getCode(), response.getRemark(), addr); |
| 981 | + SubscriptionGroupWrapper allSubscriptionGroup = new SubscriptionGroupWrapper(); |
| 982 | + allSubscriptionGroup.setSubscriptionGroupTable(subscriptionGroupTable); |
| 983 | + allSubscriptionGroup.setForbiddenTable(forbiddenTable); |
| 984 | + allSubscriptionGroup.setDataVersion(currentDataVersion); |
| 985 | + return allSubscriptionGroup; |
867 | 986 | } |
868 | 987 |
|
869 | 988 | public void registerRPCHook(RPCHook rpcHook) { |
|
0 commit comments