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



##########
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:
       Does it imply this feature is always used in Azure? I don't think so.
   Maybe move this final joiner logic to the service?

##########
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:
       Why is this required? As I discussed with Quincy, I think part of the 
purpose we think adding the virtual group is a good idea is because users may 
want more replicas than FZ count for scaling workload. If this is a target, 
then it should be an orthogonal feature than cloud support. 

##########
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:
       Validate numGroups too?

##########
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

Review comment:
       The fact that users call addVirtualTopologyGroup implies that they want 
to enable VIRTUAL_GROUP_ENABLED. I think VIRTUAL_GROUP_ENABLED is redundant.

##########
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:
       No strong preference, but I prefer to avoid using "strategy", which 
immediately hint to the code reader/lib user about partition rebalance strategy.

##########
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;

Review comment:
       Should we put it in the same cloud package? Or maybe we should remove 
the cloud-specific items here so it is more "common".

##########
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:
       Would it be easier if you take the ceiling of the float number and do 
the assignment based on that? Then we don't need step 2.

##########
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:
       Why do we need this? At least in stage one, while everyone is using the 
API to generate virtual groups at the very beginning, there is no need to check 
if it is enabled or not, right? Please correct me if my understanding is wrong.

##########
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:
       Somehow I believe you can call manuallyEnableMaintenanceMode even the 
cluster is already in the maintenance mode. If this is the case, then your 
disabling maintenance mode in line 111 will remove user's previous setup. And 
it could cause serious issues.
   Could you please confirm? We should either fail the 
manuallyEnableMaintenanceMode if the cluster is in maintenance mode, or don't 
disabling if the maintenance mode is not triggered by our API logic.

##########
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;

Review comment:
       Are we planning to support multiple strategies in the future?




-- 
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