jiajunwang commented on a change in pull request #1935:
URL: https://github.com/apache/helix/pull/1935#discussion_r789028024



##########
File path: 
helix-core/src/main/java/org/apache/helix/cloud/topology/VirtualTopologyGroupStrategy.java
##########
@@ -0,0 +1,80 @@
+package org.apache.helix.cloud.topology;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.util.HelixUtil;
+
+public enum VirtualTopologyGroupStrategy {
+
+  /**
+   * A default assignment strategy that is deterministic and stable where:
+   * 1. assignment is guaranteed consistent for same inputs.
+   * 2. number of instance shuffles is reduced.
+   */
+  DEFAULT {
+    @Override
+    public Map<String, Set<String>> computeAssignment(
+        int numGroups, String virtualGroupName, Map<String, Set<String>> 
zoneMapping) {
+      List<String> sortedInstances = 
HelixUtil.sortAndFlattenZoneMapping(zoneMapping);
+      Map<String, Set<String>> assignment = new HashMap<>();
+      int instancesPerGroup = sortedInstances.size() / numGroups;
+
+      // instances.size = instancePerGroup * numGroups + residual
+      // step 1, continuously assign following groupInd order until entering 
residual section
+      for (int instanceInd = 0; instanceInd < instancesPerGroup * numGroups; 
instanceInd++) {
+        int groupIndex = instanceInd / instancesPerGroup;
+        String groupId = computeVirtualGroupId(groupIndex, virtualGroupName);
+        assignment.putIfAbsent(groupId, new HashSet<>());
+        assignment.get(groupId).add(sortedInstances.get(instanceInd));
+      }
+      // step 2, assign the residuals, either stick to the last assigned group 
or round-robin to all groups.
+      for (int instanceInd = instancesPerGroup * numGroups; instanceInd < 
sortedInstances.size(); instanceInd++) {
+        int groupIndex = numGroups <= zoneMapping.keySet().size()
+            ? numGroups - 1
+            : instanceInd % numGroups;
+        String groupId = computeVirtualGroupId(groupIndex, virtualGroupName);
+        assignment.putIfAbsent(groupId, new HashSet<>());
+        assignment.get(groupId).add(sortedInstances.get(instanceInd));
+      }
+      return ImmutableMap.copyOf(assignment);
+    }
+  };
+
+  /**
+   * Compute the assignment for each virtual topology group.
+   *
+   * @param numGroups number of the virtual groups
+   * @param virtualGroupName virtual group name
+   * @param zoneMapping current zone mapping from zoneId to instanceIds
+   * @return the assignment as mapping from virtual group ID to instanceIds
+   */
+  public abstract Map<String, Set<String>> computeAssignment(
+      int numGroups, String virtualGroupName, Map<String, Set<String>> 
zoneMapping);
+
+  private static String computeVirtualGroupId(int groupIndex, String 
virtualGroupName) {
+    return virtualGroupName + "_" + groupIndex;

Review comment:
       I can see you did 
   
   > private static final String DOMAIN_FIELD_SPLITTER = ",";
   > private static final String DOMAIN_VALUE_JOINER = "=";
   
   for the InstanceConfig. Then why hardcode here? It's better to keep the same 
style.

##########
File path: 
helix-core/src/main/java/org/apache/helix/cloud/topology/VirtualTopologyGroupStrategy.java
##########
@@ -0,0 +1,80 @@
+package org.apache.helix.cloud.topology;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.util.HelixUtil;
+
+public enum VirtualTopologyGroupStrategy {

Review comment:
       I agree strategy fits well. But due to the existing usage, I would say, 
"arrangement" or "scheme" for this class?

##########
File path: 
helix-rest/src/main/java/org/apache/helix/rest/server/service/VirtualTopologyGroupService.java
##########
@@ -0,0 +1,163 @@
+package org.apache.helix.rest.server.service;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.helix.AccessOption;
+import org.apache.helix.ConfigAccessor;
+import org.apache.helix.HelixAdmin;
+import org.apache.helix.HelixDataAccessor;
+import org.apache.helix.HelixException;
+import org.apache.helix.common.VirtualTopologyGroupConstants;
+import org.apache.helix.cloud.topology.VirtualTopologyGroupStrategy;
+import org.apache.helix.model.CloudConfig;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.HelixConfigScope;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.builder.HelixConfigScopeBuilder;
+import org.apache.helix.rest.server.json.cluster.ClusterTopology;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+
+
+/**
+ * Service for virtual topology group.
+ */
+public class VirtualTopologyGroupService {
+  private final HelixAdmin _helixAdmin;
+  private final ClusterService _clusterService;
+  private final ConfigAccessor _configAccessor;
+  private final HelixDataAccessor _dataAccessor;
+  private final VirtualTopologyGroupStrategy _strategy;
+
+  public VirtualTopologyGroupService(HelixAdmin helixAdmin, ClusterService 
clusterService,
+      ConfigAccessor configAccessor, HelixDataAccessor dataAccessor) {
+    _helixAdmin = helixAdmin;
+    _clusterService = clusterService;
+    _configAccessor = configAccessor;
+    _dataAccessor = dataAccessor;
+    _strategy = VirtualTopologyGroupStrategy.DEFAULT;
+  }
+
+  /**
+   * Add virtual topology group for a cluster.
+   * This includes calculating the virtual group assignment for all instances 
in the cluster then update instance config
+   * and cluster config. Cluster is expected to enter maintenanceMode during 
config update, this is either enabled/disabled
+   * in place this method or handled by client side code.
+   * @param clusterName the cluster name.
+   * @param customFields custom fields, {@link 
VirtualTopologyGroupConstants#GROUP_NAME}
+   *                     and {@link 
VirtualTopologyGroupConstants#GROUP_NUMBER} are required
+   * @param enterMaintenanceMode if enabled, the cluster will enter 
maintenance mode during the setup and exit once it
+   *                             completes. Otherwise, it's expected the 
maintenanceMode is controlled by client side.
+   */
+  public void addVirtualTopologyGroup(String clusterName, Map<String, String> 
customFields, boolean enterMaintenanceMode) {
+    // only support if CLOUD_ENABLED AND VIRTUAL_GROUP_ENABLED
+    CloudConfig cloudConfig = _configAccessor.getCloudConfig(clusterName);
+    if (cloudConfig == null || !cloudConfig.isCloudEnabled()) {
+      throw new HelixException(
+          "Cloud is not enabled, addVirtualTopologyGroup is not allowed to run 
in non-cloud environment.");

Review comment:
       As we discussed offline, the cloud here does not necessarily mean a real 
cloud platform. It solely means that Helix gets topology information from the 
participant under this scenario. Meaning the topology information is 
automatically provided instead of manually populated. So this restriction makes 
sense here.

##########
File path: 
helix-rest/src/main/java/org/apache/helix/rest/server/service/VirtualTopologyGroupService.java
##########
@@ -0,0 +1,163 @@
+package org.apache.helix.rest.server.service;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.helix.AccessOption;
+import org.apache.helix.ConfigAccessor;
+import org.apache.helix.HelixAdmin;
+import org.apache.helix.HelixDataAccessor;
+import org.apache.helix.HelixException;
+import org.apache.helix.common.VirtualTopologyGroupConstants;
+import org.apache.helix.cloud.topology.VirtualTopologyGroupStrategy;
+import org.apache.helix.model.CloudConfig;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.HelixConfigScope;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.builder.HelixConfigScopeBuilder;
+import org.apache.helix.rest.server.json.cluster.ClusterTopology;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+
+
+/**
+ * Service for virtual topology group.
+ */
+public class VirtualTopologyGroupService {
+  private final HelixAdmin _helixAdmin;
+  private final ClusterService _clusterService;
+  private final ConfigAccessor _configAccessor;
+  private final HelixDataAccessor _dataAccessor;
+  private final VirtualTopologyGroupStrategy _strategy;
+
+  public VirtualTopologyGroupService(HelixAdmin helixAdmin, ClusterService 
clusterService,
+      ConfigAccessor configAccessor, HelixDataAccessor dataAccessor) {
+    _helixAdmin = helixAdmin;
+    _clusterService = clusterService;
+    _configAccessor = configAccessor;
+    _dataAccessor = dataAccessor;
+    _strategy = VirtualTopologyGroupStrategy.DEFAULT;
+  }
+
+  /**
+   * Add virtual topology group for a cluster.
+   * This includes calculating the virtual group assignment for all instances 
in the cluster then update instance config
+   * and cluster config. Cluster is expected to enter maintenanceMode during 
config update, this is either enabled/disabled
+   * in place this method or handled by client side code.
+   * @param clusterName the cluster name.
+   * @param customFields custom fields, {@link 
VirtualTopologyGroupConstants#GROUP_NAME}
+   *                     and {@link 
VirtualTopologyGroupConstants#GROUP_NUMBER} are required
+   * @param enterMaintenanceMode if enabled, the cluster will enter 
maintenance mode during the setup and exit once it
+   *                             completes. Otherwise, it's expected the 
maintenanceMode is controlled by client side.
+   */
+  public void addVirtualTopologyGroup(String clusterName, Map<String, String> 
customFields, boolean enterMaintenanceMode) {
+    // only support if CLOUD_ENABLED AND VIRTUAL_GROUP_ENABLED
+    CloudConfig cloudConfig = _configAccessor.getCloudConfig(clusterName);
+    if (cloudConfig == null || !cloudConfig.isCloudEnabled()) {
+      throw new HelixException(
+          "Cloud is not enabled, addVirtualTopologyGroup is not allowed to run 
in non-cloud environment.");
+    }
+    ClusterConfig clusterConfig = 
_configAccessor.getClusterConfig(clusterName);
+    if (!clusterConfig.isVirtualGroupEnabled()) {
+      throw new HelixException("Virtual Group is disabled in cluster " + 
clusterName);
+    }
+    // validation
+    String groupName = 
customFields.get(VirtualTopologyGroupConstants.GROUP_NAME);
+    String groupNumberStr = Preconditions.checkNotNull(
+        customFields.get(VirtualTopologyGroupConstants.GROUP_NUMBER),
+        "virtualTopologyGroupNumber cannot be empty!");
+    Preconditions.checkState(!StringUtils.isEmpty(groupName), 
"virtualTopologyGroupName cannot be empty!");
+    int numGroups = Integer.parseInt(groupNumberStr);

Review comment:
       I was thinking about negative numbers or zero. But if the group number 
is larger than the node count, can we still assign it?
   It's also OK if you let the compute class throw exceptions. But please 
ensure the exception is understandable for our customers. 
IndexOutOfBoundsException is not acceptable. 

##########
File path: 
helix-core/src/main/java/org/apache/helix/cloud/topology/VirtualTopologyGroupStrategy.java
##########
@@ -0,0 +1,80 @@
+package org.apache.helix.cloud.topology;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.util.HelixUtil;
+
+public enum VirtualTopologyGroupStrategy {
+
+  /**
+   * A default assignment strategy that is deterministic and stable where:
+   * 1. assignment is guaranteed consistent for same inputs.
+   * 2. number of instance shuffles is reduced.
+   */
+  DEFAULT {
+    @Override
+    public Map<String, Set<String>> computeAssignment(
+        int numGroups, String virtualGroupName, Map<String, Set<String>> 
zoneMapping) {
+      List<String> sortedInstances = 
HelixUtil.sortAndFlattenZoneMapping(zoneMapping);
+      Map<String, Set<String>> assignment = new HashMap<>();
+      int instancesPerGroup = sortedInstances.size() / numGroups;

Review comment:
       Not exactly, the reason you get the conclusion of 6 groups is that you 
sort the instance and compute groupIndex with "instanceInd / 
instancesPerGroup". My original idea is that we can directly use mod to get the 
index.
   However, according to what we have discussed yesterday, it might be 
problematic to assign instances of one physical zone to multiple virtual 
groups. It may effectively downgrade fault tolerance. So I assume you will have 
to change the design here. Let's discuss further when your new design is ready 
: )

##########
File path: helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
##########
@@ -52,6 +52,7 @@
     FAULT_ZONE_TYPE, // the type in which isolation should be applied on when 
Helix places the
     // replicas from same partition.
     TOPOLOGY_AWARE_ENABLED, // whether topology aware rebalance is enabled.
+    VIRTUAL_GROUP_ENABLED, // whether virtual topology group is enabled

Review comment:
       As we discussed offline yesterday, it is a must as long as we still want 
to keep the physical topology somewhere and may want to provide a way to roll 
back.
   
   But logic-wise, it introduced more dependencies. For example, what if I 
enable virtual group without enabling topology awareness, does it even makes 
sense? What about when cloud features are not enabled? I can foresee many 
questions from our users.

##########
File path: 
helix-rest/src/main/java/org/apache/helix/rest/server/service/VirtualTopologyGroupService.java
##########
@@ -0,0 +1,163 @@
+package org.apache.helix.rest.server.service;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.helix.AccessOption;
+import org.apache.helix.ConfigAccessor;
+import org.apache.helix.HelixAdmin;
+import org.apache.helix.HelixDataAccessor;
+import org.apache.helix.HelixException;
+import org.apache.helix.common.VirtualTopologyGroupConstants;
+import org.apache.helix.cloud.topology.VirtualTopologyGroupStrategy;
+import org.apache.helix.model.CloudConfig;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.HelixConfigScope;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.builder.HelixConfigScopeBuilder;
+import org.apache.helix.rest.server.json.cluster.ClusterTopology;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+
+
+/**
+ * Service for virtual topology group.
+ */
+public class VirtualTopologyGroupService {
+  private final HelixAdmin _helixAdmin;
+  private final ClusterService _clusterService;
+  private final ConfigAccessor _configAccessor;
+  private final HelixDataAccessor _dataAccessor;
+  private final VirtualTopologyGroupStrategy _strategy;
+
+  public VirtualTopologyGroupService(HelixAdmin helixAdmin, ClusterService 
clusterService,
+      ConfigAccessor configAccessor, HelixDataAccessor dataAccessor) {
+    _helixAdmin = helixAdmin;
+    _clusterService = clusterService;
+    _configAccessor = configAccessor;
+    _dataAccessor = dataAccessor;
+    _strategy = VirtualTopologyGroupStrategy.DEFAULT;
+  }
+
+  /**
+   * Add virtual topology group for a cluster.
+   * This includes calculating the virtual group assignment for all instances 
in the cluster then update instance config
+   * and cluster config. Cluster is expected to enter maintenanceMode during 
config update, this is either enabled/disabled
+   * in place this method or handled by client side code.
+   * @param clusterName the cluster name.
+   * @param customFields custom fields, {@link 
VirtualTopologyGroupConstants#GROUP_NAME}
+   *                     and {@link 
VirtualTopologyGroupConstants#GROUP_NUMBER} are required
+   * @param enterMaintenanceMode if enabled, the cluster will enter 
maintenance mode during the setup and exit once it
+   *                             completes. Otherwise, it's expected the 
maintenanceMode is controlled by client side.
+   */
+  public void addVirtualTopologyGroup(String clusterName, Map<String, String> 
customFields, boolean enterMaintenanceMode) {
+    // only support if CLOUD_ENABLED AND VIRTUAL_GROUP_ENABLED
+    CloudConfig cloudConfig = _configAccessor.getCloudConfig(clusterName);
+    if (cloudConfig == null || !cloudConfig.isCloudEnabled()) {
+      throw new HelixException(
+          "Cloud is not enabled, addVirtualTopologyGroup is not allowed to run 
in non-cloud environment.");
+    }
+    ClusterConfig clusterConfig = 
_configAccessor.getClusterConfig(clusterName);
+    if (!clusterConfig.isVirtualGroupEnabled()) {
+      throw new HelixException("Virtual Group is disabled in cluster " + 
clusterName);
+    }
+    // validation
+    String groupName = 
customFields.get(VirtualTopologyGroupConstants.GROUP_NAME);
+    String groupNumberStr = Preconditions.checkNotNull(
+        customFields.get(VirtualTopologyGroupConstants.GROUP_NUMBER),
+        "virtualTopologyGroupNumber cannot be empty!");
+    Preconditions.checkState(!StringUtils.isEmpty(groupName), 
"virtualTopologyGroupName cannot be empty!");
+    int numGroups = Integer.parseInt(groupNumberStr);
+
+    // compute group assignment
+    ClusterTopology clusterTopology = 
_clusterService.getClusterTopology(clusterName);
+    Map<String, Set<String>> assignment =
+        _strategy.computeAssignment(numGroups, groupName, 
clusterTopology.toZoneMapping());
+
+    if (enterMaintenanceMode) {

Review comment:
       > we shouldn't proceed if maintenance mode is already on?
   
   Yes, or you don't exit maintenance mode at the end.

##########
File path: 
helix-core/src/main/java/org/apache/helix/common/VirtualTopologyGroupConstants.java
##########
@@ -0,0 +1,31 @@
+package org.apache.helix.common;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.helix.cloud.azure.AzureConstants;
+
+
+public class VirtualTopologyGroupConstants {
+  public static final String GROUP_NAME = "virtualTopologyGroupName";
+  public static final String GROUP_NUMBER = "virtualTopologyGroupNumber";
+  public static final String VIRTUAL_FAULT_ZONE_TYPE = "virtualZone";
+  public static final String VIRTUAL_TOPOLOGY = new 
StringBuilder(AzureConstants.AZURE_TOPOLOGY)

Review comment:
       I don't believe the high-level design of VirtualTopologyGroup is for 
Azure only. It should be determined by the caller when they call the Rest API.
   As we discussed yesterday, whenever a cluster is "cloud-enabled", it is 
supporting virtual topology. And for Helix, "cloud-enabled" does not mean a 
specific cloud platform or even public cloud. As long as the cluster nodes can 
provide the necessary information, it is supporting necessary cloud feature 
from Helix perspective.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to