This is an automated email from the ASF dual-hosted git repository.

jxue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/helix.git


The following commit(s) were added to refs/heads/master by this push:
     new c46a70f63 Fix incompatible issue for clusterConfig mapfields 
disabledInstances (#2100)
c46a70f63 is described below

commit c46a70f6376bb8a217ea3404b8586425314e866b
Author: xyuanlu <[email protected]>
AuthorDate: Wed May 18 13:16:34 2022 -0700

    Fix incompatible issue for clusterConfig mapfields disabledInstances (#2100)
    
    Fix incompatible issue for clusterConfig mapfields
---
 .../rebalancer/util/DelayedRebalanceUtil.java      |  6 +--
 .../org/apache/helix/manager/zk/ZKHelixAdmin.java  | 15 ++++--
 .../java/org/apache/helix/model/ClusterConfig.java | 55 ++++++++++++++++++----
 .../apache/helix/util/InstanceValidationUtil.java  |  3 +-
 .../integration/TestBatchEnableInstances.java      | 15 ++++++
 .../java/org/apache/helix/mock/MockHelixAdmin.java |  7 ++-
 .../helix/rest/server/TestInstancesAccessor.java   |  7 +++
 7 files changed, 89 insertions(+), 19 deletions(-)

diff --git 
a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/util/DelayedRebalanceUtil.java
 
b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/util/DelayedRebalanceUtil.java
index 41df15005..4f48b2f93 100644
--- 
a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/util/DelayedRebalanceUtil.java
+++ 
b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/util/DelayedRebalanceUtil.java
@@ -139,10 +139,10 @@ public class DelayedRebalanceUtil {
     // check the time instance got disabled.
     if (!InstanceValidationUtil.isInstanceEnabled(instanceConfig, 
clusterConfig)) {
       long disabledTime = instanceConfig.getInstanceEnabledTime();
-      Map<String, String> disabledInstances = 
clusterConfig.getDisabledInstances();
-      if (disabledInstances.containsKey(instance)) {
+      String batchedDisabledTime = 
clusterConfig.getInstanceHelixDisabledTimeStamp(instance);
+      if (batchedDisabledTime != null && !batchedDisabledTime.isEmpty()) {
         // Update batch disable time
-        long batchDisableTime = 
Long.parseLong(clusterConfig.getInstanceHelixDisabledTimeStamp(instance));
+        long batchDisableTime = Long.parseLong(batchedDisabledTime);
         if (disabledTime == -1 || disabledTime > batchDisableTime) {
           disabledTime = batchDisableTime;
         }
diff --git 
a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java 
b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java
index 673536a89..3e5f2da13 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java
@@ -1933,17 +1933,24 @@ public class ZKHelixAdmin implements HelixAdmin {
 
         ClusterConfig clusterConfig = new ClusterConfig(currentData);
         Map<String, String> disabledInstances = new 
TreeMap<>(clusterConfig.getDisabledInstances());
+        Map<String, String> disabledInstancesWithInfo = new 
TreeMap<>(clusterConfig.getDisabledInstancesWithInfo());
         if (enabled) {
           disabledInstances.keySet().removeAll(instances);
+          disabledInstancesWithInfo.keySet().removeAll(instances);
         } else {
           for (String disabledInstance : instances) {
             // We allow user to override disabledType and reason for an 
already disabled instance.
+            // TODO: we are updating both DISABLED_INSTANCES and 
DISABLED_INSTANCES_W_INFO for
+            // backward compatible. Deprecate DISABLED_INSTANCES in the future.
             // TODO: update the history ZNode
-            disabledInstances
-                .put(disabledInstance, 
assembleInstanceBatchedDisabledInfo(disabledType, reason));
+            String timeStamp = String.valueOf(System.currentTimeMillis());
+            disabledInstances.put(disabledInstance, timeStamp);
+            disabledInstancesWithInfo
+                .put(disabledInstance, 
assembleInstanceBatchedDisabledInfo(disabledType, reason, timeStamp));
           }
         }
         clusterConfig.setDisabledInstances(disabledInstances);
+        clusterConfig.setDisabledInstancesWithInfo(disabledInstancesWithInfo);
 
         return clusterConfig.getRecord();
       }
@@ -1951,10 +1958,10 @@ public class ZKHelixAdmin implements HelixAdmin {
   }
 
   public static String assembleInstanceBatchedDisabledInfo(
-      InstanceConstants.InstanceDisabledType disabledType, String reason) {
+      InstanceConstants.InstanceDisabledType disabledType, String reason, 
String timeStamp) {
     Map<String, String> disableInfo = new TreeMap<>();
     
disableInfo.put(ClusterConfig.ClusterConfigProperty.HELIX_ENABLED_DISABLE_TIMESTAMP.toString(),
-        String.valueOf(System.currentTimeMillis()));
+        timeStamp);
     if (disabledType != null) {
       
disableInfo.put(ClusterConfig.ClusterConfigProperty.HELIX_DISABLED_TYPE.toString(),
           disabledType.toString());
diff --git a/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java 
b/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
index 485076ee4..829724142 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
@@ -34,11 +34,10 @@ import org.apache.helix.HelixProperty;
 import org.apache.helix.api.config.HelixConfigProperty;
 import org.apache.helix.api.config.StateTransitionThrottleConfig;
 import org.apache.helix.api.config.StateTransitionTimeoutConfig;
+import org.apache.helix.api.config.ViewClusterSourceConfig;
 import org.apache.helix.constants.InstanceConstants;
 import org.apache.helix.util.ConfigStringUtil;
 import org.apache.helix.zookeeper.datamodel.ZNRecord;
-import org.apache.helix.api.config.ViewClusterSourceConfig;
-import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Cluster configurations
@@ -86,6 +85,9 @@ public class ClusterConfig extends HelixProperty {
     // partitons that need recovery or in
     // error exceeds this limitation
     DISABLED_INSTANCES,
+    DISABLED_INSTANCES_WITH_INFO,
+    // disabled instances and disabled instances with info are for storing 
batch disabled instances.
+    // disabled instances will write into both 2 fields for backward 
compatibility.
 
     VIEW_CLUSTER, // Set to "true" to indicate this is a view cluster
     VIEW_CLUSTER_SOURCES, // Map field, key is the name of source cluster, 
value is
@@ -772,12 +774,32 @@ public class ClusterConfig extends HelixProperty {
     _record.setMapField(ClusterConfigProperty.DISABLED_INSTANCES.name(), 
disabledInstances);
   }
 
+  /**
+   * Set the disabled instance list with concatenated Info
+   */
+  public void setDisabledInstancesWithInfo(Map<String, String> 
disabledInstancesWithInfo) {
+    
_record.setMapField(ClusterConfigProperty.DISABLED_INSTANCES_WITH_INFO.name(),
+        disabledInstancesWithInfo);
+  }
+
   /**
    * Get current disabled instance map of <instance, disabledTimeStamp>
    * @return a non-null map of disabled instances in cluster config
    */
   public Map<String, String> getDisabledInstances() {
-    Map<String, String> disabledInstances = 
_record.getMapField(ClusterConfigProperty.DISABLED_INSTANCES.name());
+    Map<String, String> disabledInstances =
+        _record.getMapField(ClusterConfigProperty.DISABLED_INSTANCES.name());
+    return disabledInstances == null ? Collections.emptyMap() : 
disabledInstances;
+  }
+
+  /**
+   * Get current disabled instance map of
+   * <instance, disabledReason = "res, disabledType = typ, disabledTimeStamp = 
time">
+   * @return a non-null map of disabled instances in cluster config
+   */
+  public Map<String, String> getDisabledInstancesWithInfo() {
+    Map<String, String> disabledInstances =
+        
_record.getMapField(ClusterConfigProperty.DISABLED_INSTANCES_WITH_INFO.name());
     return disabledInstances == null ? Collections.emptyMap() : 
disabledInstances;
   }
 
@@ -1103,7 +1125,6 @@ public class ClusterConfig extends HelixProperty {
     }
     return idealStateRuleMap;
   }
-
   @Override
   public int hashCode() {
     return getId().hashCode();
@@ -1118,26 +1139,40 @@ public class ClusterConfig extends HelixProperty {
   }
 
   public String getPlainInstanceHelixDisabledType(String instanceName) {
-    return 
ConfigStringUtil.parseConcatenatedConfig(getDisabledInstances().get(instanceName))
+    return 
ConfigStringUtil.parseConcatenatedConfig(getDisabledInstancesWithInfo().get(instanceName))
         .get(ClusterConfigProperty.HELIX_DISABLED_TYPE.toString());
   }
 
   public String getInstanceHelixDisabledType(String instanceName) {
-    if (!getDisabledInstances().containsKey(instanceName)) {
+    if (!getDisabledInstancesWithInfo().containsKey(instanceName) &&
+        !getDisabledInstances().containsKey(instanceName)) {
       return InstanceConstants.INSTANCE_NOT_DISABLED;
     }
-    return 
ConfigStringUtil.parseConcatenatedConfig(getDisabledInstances().get(instanceName))
+    return 
ConfigStringUtil.parseConcatenatedConfig(getDisabledInstancesWithInfo().get(instanceName))
         .getOrDefault(ClusterConfigProperty.HELIX_DISABLED_TYPE.toString(),
             
InstanceConstants.InstanceDisabledType.DEFAULT_INSTANCE_DISABLE_TYPE.toString());
   }
 
+  /**
+   * @return a String representing reason.
+   * null if instance is not disabled in batch mode or do not have disabled 
reason
+   */
   public String getInstanceHelixDisabledReason(String instanceName) {
-    return 
ConfigStringUtil.parseConcatenatedConfig(getDisabledInstances().get(instanceName))
+    return 
ConfigStringUtil.parseConcatenatedConfig(getDisabledInstancesWithInfo().get(instanceName))
         .get(ClusterConfigProperty.HELIX_DISABLED_REASON.toString());
   }
 
+  /**
+   * @param instanceName
+   * @return a String representation of unix time
+   * null if the instance is not disabled in batch mode.
+   */
   public String getInstanceHelixDisabledTimeStamp(String instanceName) {
-    return 
ConfigStringUtil.parseConcatenatedConfig(getDisabledInstances().get(instanceName))
-        .get(ClusterConfigProperty.HELIX_ENABLED_DISABLE_TIMESTAMP.toString());
+    if (getDisabledInstancesWithInfo().containsKey(instanceName)) {
+      return ConfigStringUtil
+          
.parseConcatenatedConfig(getDisabledInstancesWithInfo().get(instanceName))
+          
.get(ClusterConfigProperty.HELIX_ENABLED_DISABLE_TIMESTAMP.toString());
+    }
+    return getDisabledInstances().get(instanceName);
   }
 }
diff --git 
a/helix-core/src/main/java/org/apache/helix/util/InstanceValidationUtil.java 
b/helix-core/src/main/java/org/apache/helix/util/InstanceValidationUtil.java
index 6f17d1c49..fa23372f9 100644
--- a/helix-core/src/main/java/org/apache/helix/util/InstanceValidationUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/InstanceValidationUtil.java
@@ -129,7 +129,8 @@ public class InstanceValidationUtil {
       return enabledInInstanceConfig;
     }
     boolean enabledInClusterConfig =
-        
!clusterConfig.getDisabledInstances().containsKey(instanceConfig.getInstanceName());
+        
!clusterConfig.getDisabledInstances().containsKey(instanceConfig.getInstanceName())
+        && 
!clusterConfig.getDisabledInstancesWithInfo().containsKey(instanceConfig.getInstanceName());
     return enabledInClusterConfig && enabledInInstanceConfig;
   }
 
diff --git 
a/helix-core/src/test/java/org/apache/helix/integration/TestBatchEnableInstances.java
 
b/helix-core/src/test/java/org/apache/helix/integration/TestBatchEnableInstances.java
index 6dfd0037f..6e07a373c 100644
--- 
a/helix-core/src/test/java/org/apache/helix/integration/TestBatchEnableInstances.java
+++ 
b/helix-core/src/test/java/org/apache/helix/integration/TestBatchEnableInstances.java
@@ -61,6 +61,12 @@ public class TestBatchEnableInstances extends TaskTestBase {
     for (Map<String, String> stateMap : 
externalView.getRecord().getMapFields().values()) {
       
Assert.assertTrue(!stateMap.keySet().contains(_participants[0].getInstanceName()));
     }
+    HelixDataAccessor dataAccessor =
+        new ZKHelixDataAccessor(CLUSTER_NAME, new 
ZkBaseDataAccessor<>(_gZkClient));
+    ClusterConfig clusterConfig = 
dataAccessor.getProperty(dataAccessor.keyBuilder().clusterConfig());
+    Assert.assertEquals(Long.parseLong(
+        
clusterConfig.getInstanceHelixDisabledTimeStamp(_participants[0].getInstanceName())),
+        
Long.parseLong(clusterConfig.getDisabledInstances().get(_participants[0].getInstanceName())));
     _gSetupTool.getClusterManagementTool().enableInstance(CLUSTER_NAME,
         _participants[0].getInstanceName(), true);
   }
@@ -79,9 +85,18 @@ public class TestBatchEnableInstances extends TaskTestBase {
       
Assert.assertTrue(!stateMap.keySet().contains(_participants[0].getInstanceName()));
       
Assert.assertTrue(!stateMap.keySet().contains(_participants[1].getInstanceName()));
     }
+    HelixDataAccessor dataAccessor =
+        new ZKHelixDataAccessor(CLUSTER_NAME, new 
ZkBaseDataAccessor<>(_gZkClient));
+    ClusterConfig clusterConfig = 
dataAccessor.getProperty(dataAccessor.keyBuilder().clusterConfig());
+    Assert.assertEquals(Long.parseLong(
+        
clusterConfig.getInstanceHelixDisabledTimeStamp(_participants[1].getInstanceName())),
+        
Long.parseLong(clusterConfig.getDisabledInstances().get(_participants[1].getInstanceName())));
     _gSetupTool.getClusterManagementTool().enableInstance(CLUSTER_NAME,
         Arrays.asList(_participants[0].getInstanceName(), 
_participants[1].getInstanceName()),
         true);
+    Assert.assertEquals(Long.parseLong(
+        
clusterConfig.getInstanceHelixDisabledTimeStamp(_participants[0].getInstanceName())),
+        
Long.parseLong(clusterConfig.getDisabledInstances().get(_participants[0].getInstanceName())));
   }
 
   @Test
diff --git a/helix-core/src/test/java/org/apache/helix/mock/MockHelixAdmin.java 
b/helix-core/src/test/java/org/apache/helix/mock/MockHelixAdmin.java
index 87231d5d7..4063a58ed 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/MockHelixAdmin.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/MockHelixAdmin.java
@@ -319,18 +319,23 @@ public class MockHelixAdmin implements HelixAdmin {
     ClusterConfig clusterConfig = new ClusterConfig(record);
 
     Map<String, String> disabledInstances = new TreeMap<>();
+    Map<String, String> disabledInstancesWithInfo = new TreeMap<>();
     if (clusterConfig.getDisabledInstances() != null) {
       disabledInstances.putAll(clusterConfig.getDisabledInstances());
+      
disabledInstancesWithInfo.putAll(clusterConfig.getDisabledInstancesWithInfo());
     }
     if (enabled) {
       disabledInstances.keySet().removeAll(instances);
     } else {
       for (String disabledInstance : instances) {
+        String timeStamp = String.valueOf(System.currentTimeMillis());
+        disabledInstances.put(disabledInstance, timeStamp);
         disabledInstances
-            .put(disabledInstance, 
assembleInstanceBatchedDisabledInfo(disabledType, reason));
+            .put(disabledInstance, 
assembleInstanceBatchedDisabledInfo(disabledType, reason, timeStamp));
       }
     }
     clusterConfig.setDisabledInstances(disabledInstances);
+    clusterConfig.setDisabledInstancesWithInfo(disabledInstancesWithInfo);
   }
 
   @Override
diff --git 
a/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstancesAccessor.java
 
b/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstancesAccessor.java
index 7e9058ff8..87859ffcc 100644
--- 
a/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstancesAccessor.java
+++ 
b/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstancesAccessor.java
@@ -154,6 +154,8 @@ public class TestInstancesAccessor extends 
AbstractTestClass {
     ClusterConfig clusterConfig = 
_configAccessor.getClusterConfig(CLUSTER_NAME);
     Assert.assertEquals(clusterConfig.getDisabledInstances().keySet(),
         new HashSet<>(instancesToDisable));
+    Assert.assertEquals(clusterConfig.getDisabledInstancesWithInfo().keySet(),
+        new HashSet<>(instancesToDisable));
     Assert
         .assertEquals(clusterConfig.getInstanceHelixDisabledType(CLUSTER_NAME 
+ "localhost_12918"),
             "USER_OPERATION");
@@ -171,6 +173,11 @@ public class TestInstancesAccessor extends 
AbstractTestClass {
     clusterConfig = _configAccessor.getClusterConfig(CLUSTER_NAME);
     Assert.assertEquals(clusterConfig.getDisabledInstances().keySet(),
         new HashSet<>(Arrays.asList(CLUSTER_NAME + "localhost_12919")));
+    Assert.assertEquals(clusterConfig.getDisabledInstancesWithInfo().keySet(),
+        new HashSet<>(Arrays.asList(CLUSTER_NAME + "localhost_12919")));
+    Assert.assertEquals(Long.parseLong(
+        clusterConfig.getInstanceHelixDisabledTimeStamp(CLUSTER_NAME + 
"localhost_12919")),
+        Long.parseLong(clusterConfig.getDisabledInstances().get(CLUSTER_NAME + 
"localhost_12919")));
     Assert
         .assertEquals(clusterConfig.getInstanceHelixDisabledType(CLUSTER_NAME 
+ "localhost_12918"),
             "INSTANCE_NOT_DISABLED");

Reply via email to