static Map<String, Map<Integer, BrokerRegistration>> calMain2proxyByRack(
        Map<String, List<BrokerRegistration>> rack2brokers) {
        rack2brokers.forEach((rack, brokers) -> brokers.sort(Comparator.comparingInt(BrokerRegistration::id)));

        Map<String, Map<Integer, BrokerRegistration>> newMain2proxyByRack = new HashMap<>();
        List<String> racks = rack2brokers.keySet().stream().sorted().collect(Collectors.toList());
        racks.forEach(proxyRack -> {
            Map<Integer, BrokerRegistration> newMain2proxy = new HashMap<>();
            List<ProxyNode> proxyNodes = new ArrayList<>();
            ConsistentHashRouter<ProxyNode> router = new ConsistentHashRouter<>();
            List<BrokerRegistration> proxyRackBrokers = rack2brokers.get(proxyRack);
            proxyRackBrokers.forEach(node -> {
                ProxyNode proxyNode = new ProxyNode(node);
                router.addNode(proxyNode, DEFAULT_VIRTUAL_NODE_COUNT);
                proxyNodes.add(proxyNode);
            });

            // allocate the proxy node by consistent hash
            int proxyNodeCount = 0;
            for (String rack : racks) {
                List<BrokerRegistration> brokers = rack2brokers.get(rack);
                if (Objects.equals(rack, proxyRack)) {
                    continue;
                }
                for (BrokerRegistration node : brokers) {
                    ProxyNode proxyNode = router.routeNode(Integer.toString(node.id()));
                    newMain2proxy.put(node.id(), proxyNode.node);
                    proxyNode.mainNodeIds.add(node.id());
                    proxyNodeCount++;
                }
            }
            // balance the proxy node count
            double avg = Math.ceil((double) proxyNodeCount / proxyNodes.size());
            proxyNodes.sort(Comparator.reverseOrder());
            for (ProxyNode overloadNode : proxyNodes) {
                if (overloadNode.mainNodeIds.size() <= avg) {
                    break;
                }
                // move overload node's proxied node to free node
                for (int i = proxyNodes.size() - 1; i >= 0 && overloadNode.mainNodeIds.size() > avg; i--) {
                    ProxyNode freeNode = proxyNodes.get(i);
                    if (freeNode.mainNodeIds.size() > avg - 1) {
                        continue;
                    }
                    Integer mainNodeId = overloadNode.mainNodeIds.remove(overloadNode.mainNodeIds.size() - 1);
                    newMain2proxy.put(mainNodeId, freeNode.node);
                    freeNode.mainNodeIds.add(mainNodeId);
                }
            }
            // try let controller only proxy controller
            tryFreeController(proxyNodes, avg);

            newMain2proxyByRack.put(proxyRack, newMain2proxy);
        });
        return newMain2proxyByRack;
    }
Get the proxy leader node when NOT_LEADER_OR_FOLLOWER happens.
core/src/main/java/kafka/automq/zerozone/ProxyNodeMapping.java