You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by so...@apache.org on 2020/04/09 11:05:47 UTC

[hadoop-ozone] branch HDDS-1880-Decom updated: HDDS-3361. Remove ContainerReplica states representing decomission and maintenance (#789)

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

sodonnell pushed a commit to branch HDDS-1880-Decom
in repository https://gitbox.apache.org/repos/asf/hadoop-ozone.git


The following commit(s) were added to refs/heads/HDDS-1880-Decom by this push:
     new 6fc7904  HDDS-3361. Remove ContainerReplica states representing decomission and maintenance (#789)
6fc7904 is described below

commit 6fc79045346150825906b30b3cb683fc6febb86c
Author: Stephen O'Donnell <st...@gmail.com>
AuthorDate: Thu Apr 9 12:05:35 2020 +0100

    HDDS-3361. Remove ContainerReplica states representing decomission and maintenance (#789)
---
 .../hadoop/hdds/protocol/MockDatanodeDetails.java  |   4 +
 .../proto/StorageContainerDatanodeProtocol.proto   |   2 -
 .../hdds/scm/container/ContainerReplicaCount.java  |  18 +--
 .../hdds/scm/container/ReplicationManager.java     |  11 +-
 .../hdds/scm/node/DatanodeAdminMonitorImpl.java    |   4 +
 .../hdds/scm/container/SimpleMockNodeManager.java  |   4 +
 .../hdds/scm/container/TestReplicationManager.java | 130 +++++++++++++--------
 .../states/TestContainerReplicaCount.java          | 119 +++++++++++--------
 .../hdds/scm/node/TestDatanodeAdminMonitor.java    |  83 +++++++------
 9 files changed, 228 insertions(+), 147 deletions(-)

diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/protocol/MockDatanodeDetails.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/protocol/MockDatanodeDetails.java
index 0cf3b25..f66f1ae 100644
--- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/protocol/MockDatanodeDetails.java
+++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/protocol/MockDatanodeDetails.java
@@ -17,6 +17,8 @@
  */
 package org.apache.hadoop.hdds.protocol;
 
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
+
 import java.io.IOException;
 import java.net.ServerSocket;
 import java.util.Random;
@@ -101,6 +103,8 @@ public final class MockDatanodeDetails {
         .addPort(ratisPort)
         .addPort(restPort)
         .setNetworkLocation(networkLocation)
+        .setPersistedOpState(HddsProtos.NodeOperationalState.IN_SERVICE)
+        .setPersistedOpStateExpiry(0)
         .build();
   }
 
diff --git a/hadoop-hdds/container-service/src/main/proto/StorageContainerDatanodeProtocol.proto b/hadoop-hdds/container-service/src/main/proto/StorageContainerDatanodeProtocol.proto
index fc62491..17da79b 100644
--- a/hadoop-hdds/container-service/src/main/proto/StorageContainerDatanodeProtocol.proto
+++ b/hadoop-hdds/container-service/src/main/proto/StorageContainerDatanodeProtocol.proto
@@ -185,8 +185,6 @@ message ContainerReplicaProto {
     CLOSED = 4;
     UNHEALTHY = 5;
     INVALID = 6;
-    DECOMMISSIONED = 7;
-    MAINTENANCE = 8;
   }
   required int64 containerID = 1;
   required State state = 2;
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerReplicaCount.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerReplicaCount.java
index b888fdf..bf8c3b9 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerReplicaCount.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerReplicaCount.java
@@ -18,10 +18,14 @@
 package org.apache.hadoop.hdds.scm.container;
 
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
-import org.apache.hadoop.hdds.protocol.proto
-    .StorageContainerDatanodeProtocolProtos.ContainerReplicaProto;
 import java.util.Set;
 
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.DECOMMISSIONED;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.DECOMMISSIONING;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.ENTERING_MAINTENANCE;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.IN_MAINTENANCE;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.IN_SERVICE;
+
 /**
  * Immutable object that is created with a set of ContainerReplica objects and
  * the number of in flight replica add and deletes, the container replication
@@ -57,10 +61,11 @@ public class ContainerReplicaCount {
     this.container = container;
 
     for (ContainerReplica cr : this.replica) {
-      ContainerReplicaProto.State state = cr.getState();
-      if (state == ContainerReplicaProto.State.DECOMMISSIONED) {
+      HddsProtos.NodeOperationalState state =
+          cr.getDatanodeDetails().getPersistedOpState();
+      if (state == DECOMMISSIONED || state == DECOMMISSIONING) {
         decommissionCount++;
-      } else if (state == ContainerReplicaProto.State.MAINTENANCE) {
+      } else if (state == IN_MAINTENANCE || state == ENTERING_MAINTENANCE) {
         maintenanceCount++;
       } else {
         healthyCount++;
@@ -259,8 +264,7 @@ public class ContainerReplicaCount {
     return (container.getState() == HddsProtos.LifeCycleState.CLOSED
         || container.getState() == HddsProtos.LifeCycleState.QUASI_CLOSED)
         && replica.stream()
-        .filter(r -> r.getState() != ContainerReplicaProto.State.DECOMMISSIONED)
-        .filter(r -> r.getState() != ContainerReplicaProto.State.MAINTENANCE)
+        .filter(r -> r.getDatanodeDetails().getPersistedOpState() == IN_SERVICE)
         .allMatch(r -> ReplicationManager.compareState(
             container.getState(), r.getState()));
   }
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ReplicationManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ReplicationManager.java
index ae7242a..eb10ae6 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ReplicationManager.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ReplicationManager.java
@@ -37,6 +37,7 @@ import org.apache.hadoop.hdds.conf.Config;
 import org.apache.hadoop.hdds.conf.ConfigGroup;
 import org.apache.hadoop.hdds.conf.ConfigType;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleState;
 import org.apache.hadoop.hdds.protocol.proto
     .StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State;
@@ -544,9 +545,7 @@ public class ReplicationManager implements MetricsSource, SafeModeNotification {
       final List<DatanodeDetails> source = replicas.stream()
           .filter(r ->
               r.getState() == State.QUASI_CLOSED ||
-              r.getState() == State.CLOSED ||
-              r.getState() == State.DECOMMISSIONED ||
-              r.getState() == State.MAINTENANCE)
+              r.getState() == State.CLOSED)
           // Exclude stale and dead nodes. This is particularly important for
           // maintenance nodes, as the replicas will remain present in the
           // container manager, even when they go dead.
@@ -623,9 +622,9 @@ public class ReplicationManager implements MetricsSource, SafeModeNotification {
       // Replica which are maintenance or decommissioned are not eligible to
       // be removed, as they do not count toward over-replication and they also
       // many not be available
-      eligibleReplicas.removeIf(r -> (r.getState() == State.MAINTENANCE
-          || r.getState() == State.DECOMMISSIONED));
-
+      eligibleReplicas.removeIf(r ->
+          r.getDatanodeDetails().getPersistedOpState() !=
+              HddsProtos.NodeOperationalState.IN_SERVICE);
       final List<ContainerReplica> unhealthyReplicas = eligibleReplicas
           .stream()
           .filter(r -> !compareState(container.getState(), r.getState()))
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/DatanodeAdminMonitorImpl.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/DatanodeAdminMonitorImpl.java
index a1d47fd..f9d1a32 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/DatanodeAdminMonitorImpl.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/DatanodeAdminMonitorImpl.java
@@ -202,6 +202,10 @@ public class DatanodeAdminMonitorImpl implements DatanodeAdminMonitor {
 
         if (status.isDecommissioning() || status.isEnteringMaintenance()) {
           if (checkPipelinesClosedOnNode(dn)
+              // Ensure the DN has received and persisted the current maint
+              // state.
+              && status.getOperationalState()
+                  == dn.getDatanodeDetails().getPersistedOpState()
               && checkContainersReplicatedOnNode(dn)) {
             // CheckContainersReplicatedOnNode may take a short time to run
             // so after it completes, re-get the nodestatus to check the health
diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/SimpleMockNodeManager.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/SimpleMockNodeManager.java
index 7e6bf0c..19ca69e 100644
--- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/SimpleMockNodeManager.java
+++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/SimpleMockNodeManager.java
@@ -52,10 +52,14 @@ public class SimpleMockNodeManager implements NodeManager {
   private Map<UUID, Set<ContainerID>> containerMap = new ConcurrentHashMap<>();
 
   public void register(DatanodeDetails dd, NodeStatus status) {
+    dd.setPersistedOpState(status.getOperationalState());
+    dd.setPersistedOpStateExpiryEpochSec(status.getOpStateExpiryEpochSeconds());
     nodeMap.put(dd.getUuid(), new DatanodeInfo(dd, status));
   }
 
   public void setNodeStatus(DatanodeDetails dd, NodeStatus status) {
+    dd.setPersistedOpState(status.getOperationalState());
+    dd.setPersistedOpStateExpiryEpochSec(status.getOpStateExpiryEpochSeconds());
     DatanodeInfo dni = nodeMap.get(dd.getUuid());
     dni.setNodeStatus(status);
   }
diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestReplicationManager.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestReplicationManager.java
index 1c83231..3ed9f38 100644
--- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestReplicationManager.java
+++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestReplicationManager.java
@@ -18,6 +18,7 @@
 
 package org.apache.hadoop.hdds.scm.container;
 
+import com.google.common.primitives.Longs;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
@@ -56,6 +57,13 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 import static org.apache.hadoop.hdds.protocol.MockDatanodeDetails.createDatanodeDetails;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.DECOMMISSIONED;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.DECOMMISSIONING;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.IN_MAINTENANCE;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.IN_SERVICE;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeState.HEALTHY;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeState.STALE;
+import static org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State.CLOSED;
 import static org.apache.hadoop.hdds.scm.TestUtils.getContainer;
 import static org.apache.hadoop.hdds.scm.TestUtils.getReplicas;
 import static org.apache.hadoop.hdds.protocol.MockDatanodeDetails.randomDatanodeDetails;
@@ -596,7 +604,7 @@ public class TestReplicationManager {
       throws SCMException, ContainerNotFoundException, InterruptedException {
     final ContainerInfo container = getContainer(LifeCycleState.CLOSED);
     final ContainerID id = container.containerID();
-    final Set<ContainerReplica> replicas = getReplicas(id, State.CLOSED,
+    final Set<ContainerReplica> replicas = getReplicas(id, CLOSED,
         randomDatanodeDetails(),
         randomDatanodeDetails(),
         randomDatanodeDetails());
@@ -633,8 +641,10 @@ public class TestReplicationManager {
   @Test
   public void testUnderReplicatedDueToDecommission() throws
       SCMException, ContainerNotFoundException, InterruptedException {
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.CLOSED, State.DECOMMISSIONED, State.DECOMMISSIONED);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, new NodeStatus(IN_SERVICE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONING, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONING, HEALTHY), CLOSED);
     assertReplicaScheduled(2);
   }
 
@@ -645,8 +655,10 @@ public class TestReplicationManager {
   @Test
   public void testUnderReplicatedDueToAllDecommission() throws
       SCMException, ContainerNotFoundException, InterruptedException {
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.DECOMMISSIONED, State.DECOMMISSIONED, State.DECOMMISSIONED);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONING, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONING, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONING, HEALTHY), CLOSED);
     assertReplicaScheduled(3);
   }
 
@@ -657,8 +669,11 @@ public class TestReplicationManager {
   @Test
   public void testCorrectlyReplicatedWithDecommission() throws
       SCMException, ContainerNotFoundException, InterruptedException {
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.CLOSED, State.CLOSED, State.CLOSED, State.DECOMMISSIONED);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, new NodeStatus(IN_SERVICE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_SERVICE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_SERVICE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONING, HEALTHY), CLOSED);
     assertReplicaScheduled(0);
   }
 
@@ -669,8 +684,10 @@ public class TestReplicationManager {
   @Test
   public void testUnderReplicatedDueToMaintenance() throws
       SCMException, ContainerNotFoundException, InterruptedException {
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.CLOSED, State.MAINTENANCE, State.MAINTENANCE);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, new NodeStatus(IN_SERVICE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
     assertReplicaScheduled(1);
   }
 
@@ -686,8 +703,10 @@ public class TestReplicationManager {
         new ReplicationManagerConfiguration();
     newConf.setMaintenanceReplicaMinimum(1);
     createReplicationManager(newConf);
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.CLOSED, State.MAINTENANCE, State.MAINTENANCE);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, new NodeStatus(IN_SERVICE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
     assertReplicaScheduled(0);
   }
 
@@ -703,8 +722,10 @@ public class TestReplicationManager {
         new ReplicationManagerConfiguration();
     newConf.setMaintenanceReplicaMinimum(1);
     createReplicationManager(newConf);
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.MAINTENANCE, State.MAINTENANCE, State.MAINTENANCE);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
     assertReplicaScheduled(1);
   }
 
@@ -715,8 +736,10 @@ public class TestReplicationManager {
   @Test
   public void testUnderReplicatedDueToAllMaintenance() throws
       SCMException, ContainerNotFoundException, InterruptedException {
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.MAINTENANCE, State.MAINTENANCE, State.MAINTENANCE);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
     assertReplicaScheduled(2);
   }
 
@@ -727,8 +750,11 @@ public class TestReplicationManager {
   @Test
   public void testCorrectlyReplicatedWithMaintenance() throws
       SCMException, ContainerNotFoundException, InterruptedException {
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.CLOSED, State.CLOSED, State.MAINTENANCE, State.MAINTENANCE);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, new NodeStatus(IN_SERVICE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_SERVICE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
     assertReplicaScheduled(0);
   }
 
@@ -739,9 +765,11 @@ public class TestReplicationManager {
   @Test
   public void testUnderReplicatedWithDecommissionAndMaintenance() throws
       SCMException, ContainerNotFoundException, InterruptedException {
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.DECOMMISSIONED, State.DECOMMISSIONED, State.MAINTENANCE,
-        State.MAINTENANCE);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONED, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONED, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
     assertReplicaScheduled(2);
   }
 
@@ -754,9 +782,14 @@ public class TestReplicationManager {
   @Test
   public void testOverReplicatedClosedContainerWithDecomAndMaint()
       throws SCMException, ContainerNotFoundException, InterruptedException {
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        State.DECOMMISSIONED, State.MAINTENANCE,
-        State.CLOSED, State.CLOSED, State.CLOSED, State.CLOSED);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, NodeStatus.inServiceHealthy(), CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONED, HEALTHY), CLOSED);
+    addReplica(container, new NodeStatus(IN_MAINTENANCE, HEALTHY), CLOSED);
+    addReplica(container, NodeStatus.inServiceHealthy(), CLOSED);
+    addReplica(container, NodeStatus.inServiceHealthy(), CLOSED);
+    addReplica(container, NodeStatus.inServiceHealthy(), CLOSED);
+    addReplica(container, NodeStatus.inServiceHealthy(), CLOSED);
 
     final int currentDeleteCommandCount = datanodeCommandHandler
         .getInvocationCount(SCMCommandProto.Type.deleteContainerCommand);
@@ -764,14 +797,14 @@ public class TestReplicationManager {
     replicationManager.processContainersNow();
     // Wait for EventQueue to call the event handler
     Thread.sleep(100L);
-    Assert.assertEquals(currentDeleteCommandCount + 1, datanodeCommandHandler
+    Assert.assertEquals(currentDeleteCommandCount + 2, datanodeCommandHandler
         .getInvocationCount(SCMCommandProto.Type.deleteContainerCommand));
     // Get the DECOM and Maint replica and ensure none of them are scheduled
     // for removal
     Set<ContainerReplica> decom =
         containerStateManager.getContainerReplicas(container.containerID())
         .stream()
-        .filter(r -> r.getState() != State.CLOSED)
+        .filter(r -> r.getDatanodeDetails().getPersistedOpState() != IN_SERVICE)
         .collect(Collectors.toSet());
     for (ContainerReplica r : decom) {
       Assert.assertFalse(datanodeCommandHandler.received(
@@ -789,38 +822,43 @@ public class TestReplicationManager {
   @Test
   public void testUnderReplicatedNotHealthySource()
       throws SCMException, ContainerNotFoundException, InterruptedException {
-    final ContainerInfo container = setupReplicas(LifeCycleState.CLOSED,
-        NodeStatus.inServiceStale(),
-        State.CLOSED, State.DECOMMISSIONED, State.DECOMMISSIONED);
+    final ContainerInfo container = createContainer(LifeCycleState.CLOSED);
+    addReplica(container, NodeStatus.inServiceStale(), CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONED, STALE), CLOSED);
+    addReplica(container, new NodeStatus(DECOMMISSIONED, STALE), CLOSED);
     // There should be replica scheduled, but as all nodes are stale, nothing
     // gets scheduled.
     assertReplicaScheduled(0);
   }
 
-  private ContainerInfo setupReplicas(
-      LifeCycleState containerState, State... states)
-      throws SCMException, ContainerNotFoundException {
-    return setupReplicas(containerState, NodeStatus.inServiceHealthy(), states);
-  }
-
-  private ContainerInfo setupReplicas(
-      LifeCycleState containerState, NodeStatus allNodesStatus, State... states)
-      throws SCMException, ContainerNotFoundException {
+  private ContainerInfo createContainer(LifeCycleState containerState)
+      throws SCMException {
     final ContainerInfo container = getContainer(containerState);
     final ContainerID id = container.containerID();
     containerStateManager.loadContainer(container);
-    final UUID originNodeId = UUID.randomUUID();
-
-    for (State s : states) {
-      DatanodeDetails dn = randomDatanodeDetails();
-      nodeManager.register(dn, allNodesStatus);
-      final ContainerReplica replica = getReplicas(
-          id, s, 1000L, originNodeId, dn);
-      containerStateManager.updateContainerReplica(id, replica);
-    }
     return container;
   }
 
+  private ContainerReplica addReplica(ContainerInfo container,
+      NodeStatus nodeStatus, State replicaState)
+      throws ContainerNotFoundException {
+    DatanodeDetails dn = randomDatanodeDetails();
+    dn.setPersistedOpState(nodeStatus.getOperationalState());
+    dn.setPersistedOpStateExpiryEpochSec(
+        nodeStatus.getOpStateExpiryEpochSeconds());
+    nodeManager.register(dn, nodeStatus);
+    // Using the same originID for all replica in the container set. If each
+    // replica has a unique originID, it causes problems in ReplicationManager
+    // when processing over-replicated containers.
+    final UUID originNodeId =
+        UUID.nameUUIDFromBytes(Longs.toByteArray(container.getContainerID()));
+    final ContainerReplica replica = getReplicas(
+        container.containerID(), CLOSED, 1000L, originNodeId, dn);
+    containerStateManager
+        .updateContainerReplica(container.containerID(), replica);
+    return replica;
+  }
+
   private void assertReplicaScheduled(int delta) throws InterruptedException {
     final int currentReplicateCommandCount = datanodeCommandHandler
         .getInvocationCount(SCMCommandProto.Type.replicateContainerCommand);
diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/states/TestContainerReplicaCount.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/states/TestContainerReplicaCount.java
index f6e2187..3c7c952 100644
--- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/states/TestContainerReplicaCount.java
+++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/states/TestContainerReplicaCount.java
@@ -20,8 +20,6 @@ package org.apache.hadoop.hdds.scm.container.states;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
 import org.apache.hadoop.hdds.protocol.MockDatanodeDetails;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
-import org.apache.hadoop.hdds.protocol.proto
-    .StorageContainerDatanodeProtocolProtos.ContainerReplicaProto;
 import org.apache.hadoop.hdds.scm.container.ContainerID;
 import org.apache.hadoop.hdds.scm.container.ContainerInfo;
 import org.apache.hadoop.hdds.scm.container.ContainerReplica;
@@ -31,16 +29,19 @@ import org.junit.Test;
 import java.util.*;
 import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.assertTrue;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos
+    .NodeOperationalState.DECOMMISSIONED;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos
+    .NodeOperationalState.DECOMMISSIONING;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos
+    .NodeOperationalState.ENTERING_MAINTENANCE;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos
+    .NodeOperationalState.IN_MAINTENANCE;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos
+    .NodeOperationalState.IN_SERVICE;
 import static org.apache.hadoop.hdds.protocol.proto
     .StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State.CLOSED;
-import static org.apache.hadoop.hdds.protocol.proto
-    .StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State.OPEN;
-import static org.apache.hadoop.hdds.protocol.proto
-    .StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State
-    .DECOMMISSIONED;
-import static org.apache.hadoop.hdds.protocol.proto
-    .StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State
-    .MAINTENANCE;
+import static org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State.OPEN;
 import static org.junit.Assert.assertFalse;
 
 /**
@@ -54,7 +55,8 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testThreeHealthyReplica() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED, CLOSED, CLOSED);
+    Set<ContainerReplica> replica =
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -63,7 +65,7 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testTwoHealthyReplica() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED, CLOSED);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -72,7 +74,7 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testOneHealthyReplica() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -82,7 +84,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testTwoHealthyAndInflightAdd() {
 
-    Set<ContainerReplica> replica = registerNodes(CLOSED, CLOSED);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 1, 0, 3, 2);
@@ -96,7 +98,8 @@ public class TestContainerReplicaCount {
    * completes there will be 4 healthy and it will get taken care of then.
    */
   public void testThreeHealthyAndInflightAdd() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED, CLOSED, CLOSED);
+    Set<ContainerReplica> replica =
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 1, 0, 3, 2);
@@ -109,7 +112,8 @@ public class TestContainerReplicaCount {
    * under replicated, we go ahead and schedule another replica to be added.
    */
   public void testThreeHealthyAndInflightDelete() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED, CLOSED, CLOSED);
+    Set<ContainerReplica> replica =
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 1, 3, 2);
@@ -122,7 +126,8 @@ public class TestContainerReplicaCount {
    * inflight del could succeed, leaving only 2 healthy replicas.
    */
   public void testThreeHealthyAndInflightAddAndInFlightDelete() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED, CLOSED, CLOSED);
+    Set<ContainerReplica> replica =
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 1, 1, 3, 2);
@@ -132,7 +137,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testFourHealthyReplicas() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, CLOSED, CLOSED, CLOSED);
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -142,7 +147,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testFourHealthyReplicasAndInFlightDelete() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, CLOSED, CLOSED, CLOSED);
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 1, 3, 2);
@@ -152,7 +157,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testFourHealthyReplicasAndTwoInFlightDelete() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, CLOSED, CLOSED, CLOSED);
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 2, 3, 2);
@@ -161,7 +166,7 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testOneHealthyReplicaRepFactorOne() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 1, 2);
@@ -170,7 +175,7 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testOneHealthyReplicaRepFactorOneInFlightDelete() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 1, 1, 2);
@@ -179,7 +184,7 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testTwoHealthyReplicaTwoInflightAdd() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED, CLOSED);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 2, 0, 3, 2);
@@ -192,8 +197,8 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testThreeHealthyAndTwoDecommission() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED, CLOSED, CLOSED,
-        DECOMMISSIONED, DECOMMISSIONED);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE, IN_SERVICE,
+        IN_SERVICE, DECOMMISSIONING, DECOMMISSIONING);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -203,7 +208,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testOneDecommissionedReplica() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, CLOSED, DECOMMISSIONED);
+        registerNodes(IN_SERVICE, IN_SERVICE, DECOMMISSIONING);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -213,7 +218,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testTwoHealthyOneDecommissionedneInFlightAdd() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, CLOSED, DECOMMISSIONED);
+        registerNodes(IN_SERVICE, IN_SERVICE, DECOMMISSIONED);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 1, 0, 3, 2);
@@ -251,7 +256,7 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testOneHealthyOneDecommissioningRepFactorOne() {
-    Set<ContainerReplica> replica = registerNodes(DECOMMISSIONED, CLOSED);
+    Set<ContainerReplica> replica = registerNodes(DECOMMISSIONED, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 1, 2);
@@ -265,7 +270,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testOneHealthyTwoMaintenanceMinRepOfTwo() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, MAINTENANCE, MAINTENANCE);
+        registerNodes(IN_SERVICE, IN_MAINTENANCE, IN_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -274,8 +279,8 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testOneHealthyThreeMaintenanceMinRepOfTwo() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED,
-        MAINTENANCE, MAINTENANCE, MAINTENANCE);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE,
+        IN_MAINTENANCE, IN_MAINTENANCE, ENTERING_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -285,7 +290,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testOneHealthyTwoMaintenanceMinRepOfOne() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, MAINTENANCE, MAINTENANCE);
+        registerNodes(IN_SERVICE, IN_MAINTENANCE, ENTERING_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 1);
@@ -294,8 +299,8 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testOneHealthyThreeMaintenanceMinRepOfTwoInFlightAdd() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED,
-        MAINTENANCE, MAINTENANCE, MAINTENANCE);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE,
+        IN_MAINTENANCE, ENTERING_MAINTENANCE, IN_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 1, 0, 3, 2);
@@ -305,7 +310,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testAllMaintenance() {
     Set<ContainerReplica> replica =
-        registerNodes(MAINTENANCE, MAINTENANCE, MAINTENANCE);
+        registerNodes(IN_MAINTENANCE, ENTERING_MAINTENANCE, IN_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -319,8 +324,8 @@ public class TestContainerReplicaCount {
    * come back online, and then deal with them.
    */
   public void testThreeHealthyTwoInMaintenance() {
-    Set<ContainerReplica> replica = registerNodes(CLOSED, CLOSED, CLOSED,
-        MAINTENANCE, MAINTENANCE);
+    Set<ContainerReplica> replica = registerNodes(IN_SERVICE, IN_SERVICE,
+        IN_SERVICE, IN_MAINTENANCE, ENTERING_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -335,7 +340,8 @@ public class TestContainerReplicaCount {
    */
   public void testFourHealthyOneInMaintenance() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, CLOSED, CLOSED, CLOSED, MAINTENANCE);
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE, IN_SERVICE,
+            IN_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -344,7 +350,7 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testOneMaintenanceMinRepOfTwoRepFactorOne() {
-    Set<ContainerReplica> replica = registerNodes(MAINTENANCE);
+    Set<ContainerReplica> replica = registerNodes(IN_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 1, 2);
@@ -353,7 +359,7 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testOneMaintenanceMinRepOfTwoRepFactorOneInFlightAdd() {
-    Set<ContainerReplica> replica = registerNodes(MAINTENANCE);
+    Set<ContainerReplica> replica = registerNodes(IN_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 1, 0, 1, 2);
@@ -362,7 +368,7 @@ public class TestContainerReplicaCount {
 
   @Test
   public void testOneHealthyOneMaintenanceRepFactorOne() {
-    Set<ContainerReplica> replica = registerNodes(MAINTENANCE, CLOSED);
+    Set<ContainerReplica> replica = registerNodes(IN_MAINTENANCE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 1, 2);
@@ -372,7 +378,8 @@ public class TestContainerReplicaCount {
   @Test
   public void testTwoDecomTwoMaintenanceOneInflightAdd() {
     Set<ContainerReplica> replica =
-        registerNodes(DECOMMISSIONED, DECOMMISSIONED, MAINTENANCE, MAINTENANCE);
+        registerNodes(DECOMMISSIONED, DECOMMISSIONING,
+            IN_MAINTENANCE, ENTERING_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 1, 0, 3, 2);
@@ -382,7 +389,7 @@ public class TestContainerReplicaCount {
   @Test
   public void testHealthyContainerIsHealthy() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, CLOSED, CLOSED);
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -392,7 +399,21 @@ public class TestContainerReplicaCount {
   @Test
   public void testIsHealthyWithDifferentReplicaStateNotHealthy() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, CLOSED, OPEN);
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_SERVICE);
+    for (ContainerReplica r : replica) {
+      DatanodeDetails dn = r.getDatanodeDetails();
+
+      ContainerReplica replace = new ContainerReplica.ContainerReplicaBuilder()
+          .setContainerID(new ContainerID(1))
+          .setContainerState(OPEN)
+          .setDatanodeDetails(dn)
+          .setOriginNodeId(dn.getUuid())
+          .setSequenceId(1)
+          .build();
+      replica.remove(r);
+      replica.add(replace);
+      break;
+    }
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -402,7 +423,8 @@ public class TestContainerReplicaCount {
   @Test
   public void testIsHealthyWithMaintReplicaIsHealthy() {
     Set<ContainerReplica> replica =
-        registerNodes(CLOSED, CLOSED, MAINTENANCE, MAINTENANCE);
+        registerNodes(IN_SERVICE, IN_SERVICE, IN_MAINTENANCE,
+            ENTERING_MAINTENANCE);
     ContainerInfo container = createContainer(HddsProtos.LifeCycleState.CLOSED);
     ContainerReplicaCount rcnt =
         new ContainerReplicaCount(container, replica, 0, 0, 3, 2);
@@ -418,13 +440,14 @@ public class TestContainerReplicaCount {
   }
 
   private Set<ContainerReplica> registerNodes(
-      ContainerReplicaProto.State... states) {
+      HddsProtos.NodeOperationalState... states) {
     Set<ContainerReplica> replica = new HashSet<>();
-    for (ContainerReplicaProto.State s : states) {
+    for (HddsProtos.NodeOperationalState s : states) {
       DatanodeDetails dn = MockDatanodeDetails.randomDatanodeDetails();
+      dn.setPersistedOpState(s);
       replica.add(new ContainerReplica.ContainerReplicaBuilder()
           .setContainerID(new ContainerID(1))
-          .setContainerState(s)
+          .setContainerState(CLOSED)
           .setDatanodeDetails(dn)
           .setOriginNodeId(dn.getUuid())
           .setSequenceId(1)
diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/node/TestDatanodeAdminMonitor.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/node/TestDatanodeAdminMonitor.java
index cb78703..0592f94 100644
--- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/node/TestDatanodeAdminMonitor.java
+++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/node/TestDatanodeAdminMonitor.java
@@ -41,6 +41,11 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.assertTrue;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.DECOMMISSIONED;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.ENTERING_MAINTENANCE;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.IN_MAINTENANCE;
+import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.IN_SERVICE;
+import static org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State.CLOSED;
 import static org.mockito.Mockito.reset;
 
 /**
@@ -126,7 +131,7 @@ public class TestDatanodeAdminMonitor {
     nodeManager.setPipelines(dn1, 0);
     monitor.run();
     assertEquals(0, monitor.getTrackedNodeCount());
-    assertEquals(HddsProtos.NodeOperationalState.DECOMMISSIONED,
+    assertEquals(DECOMMISSIONED,
         nodeManager.getNodeStatus(dn1).getOperationalState());
   }
 
@@ -151,7 +156,7 @@ public class TestDatanodeAdminMonitor {
     monitor.run();
     assertEquals(0, monitor.getTrackedNodeCount());
     NodeStatus newStatus = nodeManager.getNodeStatus(dn1);
-    assertEquals(HddsProtos.NodeOperationalState.DECOMMISSIONED,
+    assertEquals(DECOMMISSIONED,
         newStatus.getOperationalState());
   }
 
@@ -168,9 +173,9 @@ public class TestDatanodeAdminMonitor {
     // always have a DECOMMISSIONED replica.
     mockGetContainerReplicaCount(
         HddsProtos.LifeCycleState.CLOSED,
-        ContainerReplicaProto.State.DECOMMISSIONED,
-        ContainerReplicaProto.State.CLOSED,
-        ContainerReplicaProto.State.CLOSED);
+        DECOMMISSIONED,
+        IN_SERVICE,
+        IN_SERVICE);
 
     // Run the monitor for the first time and the node will transition to
     // REPLICATE_CONTAINERS as there are no pipelines to close.
@@ -195,9 +200,9 @@ public class TestDatanodeAdminMonitor {
     // complete which will end the decommission workflow
     mockGetContainerReplicaCount(
         HddsProtos.LifeCycleState.CLOSED,
-        ContainerReplicaProto.State.CLOSED,
-        ContainerReplicaProto.State.CLOSED,
-        ContainerReplicaProto.State.CLOSED);
+        IN_SERVICE,
+        IN_SERVICE,
+        IN_SERVICE);
 
     monitor.run();
 
@@ -205,7 +210,7 @@ public class TestDatanodeAdminMonitor {
     assertEquals(3, node.getSufficientlyReplicatedContainers());
     assertEquals(0, node.getUnHealthyContainers());
     assertEquals(0, node.getUnderReplicatedContainers());
-    assertEquals(HddsProtos.NodeOperationalState.DECOMMISSIONED,
+    assertEquals(DECOMMISSIONED,
         nodeManager.getNodeStatus(dn1).getOperationalState());
   }
 
@@ -220,9 +225,9 @@ public class TestDatanodeAdminMonitor {
     nodeManager.setContainers(dn1, generateContainers(3));
     mockGetContainerReplicaCount(
         HddsProtos.LifeCycleState.CLOSED,
-        ContainerReplicaProto.State.DECOMMISSIONED,
-        ContainerReplicaProto.State.CLOSED,
-        ContainerReplicaProto.State.CLOSED);
+        DECOMMISSIONED,
+        IN_SERVICE,
+        IN_SERVICE);
 
     // Add the node to the monitor, it should have 3 under-replicated containers
     // after the first run
@@ -237,11 +242,11 @@ public class TestDatanodeAdminMonitor {
     // Set the node to dead, and then the workflow should get aborted, setting
     // the node state back to IN_SERVICE on the next run.
     nodeManager.setNodeStatus(dn1,
-        new NodeStatus(HddsProtos.NodeOperationalState.IN_SERVICE,
+        new NodeStatus(IN_SERVICE,
             HddsProtos.NodeState.HEALTHY));
     monitor.run();
     assertEquals(0, monitor.getTrackedNodeCount());
-    assertEquals(HddsProtos.NodeOperationalState.IN_SERVICE,
+    assertEquals(IN_SERVICE,
         nodeManager.getNodeStatus(dn1).getOperationalState());
   }
 
@@ -256,9 +261,7 @@ public class TestDatanodeAdminMonitor {
     nodeManager.setContainers(dn1, generateContainers(3));
     mockGetContainerReplicaCount(
         HddsProtos.LifeCycleState.CLOSED,
-        ContainerReplicaProto.State.DECOMMISSIONED,
-        ContainerReplicaProto.State.CLOSED,
-        ContainerReplicaProto.State.CLOSED);
+        DECOMMISSIONED, IN_SERVICE, IN_SERVICE);
 
     // Add the node to the monitor, it should have 3 under-replicated containers
     // after the first run
@@ -277,7 +280,7 @@ public class TestDatanodeAdminMonitor {
             HddsProtos.NodeState.DEAD));
     monitor.run();
     assertEquals(0, monitor.getTrackedNodeCount());
-    assertEquals(HddsProtos.NodeOperationalState.IN_SERVICE,
+    assertEquals(IN_SERVICE,
         nodeManager.getNodeStatus(dn1).getOperationalState());
   }
 
@@ -286,7 +289,7 @@ public class TestDatanodeAdminMonitor {
       throws NodeNotFoundException {
     DatanodeDetails dn1 = MockDatanodeDetails.randomDatanodeDetails();
     nodeManager.register(dn1,
-        new NodeStatus(HddsProtos.NodeOperationalState.ENTERING_MAINTENANCE,
+        new NodeStatus(ENTERING_MAINTENANCE,
             HddsProtos.NodeState.HEALTHY));
 
     // Add the node to the monitor, it should transiting to
@@ -308,7 +311,7 @@ public class TestDatanodeAdminMonitor {
     node.setMaintenanceEnd(-1);
     monitor.run();
     assertEquals(0, monitor.getTrackedNodeCount());
-    assertEquals(HddsProtos.NodeOperationalState.IN_SERVICE,
+    assertEquals(IN_SERVICE,
         nodeManager.getNodeStatus(dn1).getOperationalState());
   }
 
@@ -317,7 +320,7 @@ public class TestDatanodeAdminMonitor {
       throws NodeNotFoundException {
     DatanodeDetails dn1 = MockDatanodeDetails.randomDatanodeDetails();
     nodeManager.register(dn1,
-        new NodeStatus(HddsProtos.NodeOperationalState.ENTERING_MAINTENANCE,
+        new NodeStatus(ENTERING_MAINTENANCE,
             HddsProtos.NodeState.HEALTHY));
     // Ensure the node has some pipelines
     nodeManager.setPipelines(dn1, 2);
@@ -333,7 +336,7 @@ public class TestDatanodeAdminMonitor {
     node.setMaintenanceEnd(-1);
     monitor.run();
     assertEquals(0, monitor.getTrackedNodeCount());
-    assertEquals(HddsProtos.NodeOperationalState.IN_SERVICE,
+    assertEquals(IN_SERVICE,
         nodeManager.getNodeStatus(dn1).getOperationalState());
   }
 
@@ -342,15 +345,15 @@ public class TestDatanodeAdminMonitor {
       throws ContainerNotFoundException, NodeNotFoundException {
     DatanodeDetails dn1 = MockDatanodeDetails.randomDatanodeDetails();
     nodeManager.register(dn1,
-        new NodeStatus(HddsProtos.NodeOperationalState.ENTERING_MAINTENANCE,
+        new NodeStatus(ENTERING_MAINTENANCE,
             HddsProtos.NodeState.HEALTHY));
 
     nodeManager.setContainers(dn1, generateContainers(3));
     mockGetContainerReplicaCount(
         HddsProtos.LifeCycleState.CLOSED,
-        ContainerReplicaProto.State.MAINTENANCE,
-        ContainerReplicaProto.State.MAINTENANCE,
-        ContainerReplicaProto.State.MAINTENANCE);
+        IN_MAINTENANCE,
+        ENTERING_MAINTENANCE,
+        IN_MAINTENANCE);
 
     // Add the node to the monitor, it should transiting to
     // REPLICATE_CONTAINERS as the containers are under-replicated for
@@ -365,7 +368,7 @@ public class TestDatanodeAdminMonitor {
     node.setMaintenanceEnd(-1);
     monitor.run();
     assertEquals(0, monitor.getTrackedNodeCount());
-    assertEquals(HddsProtos.NodeOperationalState.IN_SERVICE,
+    assertEquals(IN_SERVICE,
         nodeManager.getNodeStatus(dn1).getOperationalState());
   }
 
@@ -374,7 +377,7 @@ public class TestDatanodeAdminMonitor {
       throws NodeNotFoundException {
     DatanodeDetails dn1 = MockDatanodeDetails.randomDatanodeDetails();
     nodeManager.register(dn1,
-        new NodeStatus(HddsProtos.NodeOperationalState.ENTERING_MAINTENANCE,
+        new NodeStatus(ENTERING_MAINTENANCE,
             HddsProtos.NodeState.HEALTHY));
 
     // Add the node to the monitor, it should transiting to
@@ -402,7 +405,7 @@ public class TestDatanodeAdminMonitor {
       throws NodeNotFoundException {
     DatanodeDetails dn1 = MockDatanodeDetails.randomDatanodeDetails();
     nodeManager.register(dn1,
-        new NodeStatus(HddsProtos.NodeOperationalState.ENTERING_MAINTENANCE,
+        new NodeStatus(ENTERING_MAINTENANCE,
             HddsProtos.NodeState.HEALTHY));
 
     // Add the node to the monitor, it should transiting to
@@ -418,7 +421,7 @@ public class TestDatanodeAdminMonitor {
     monitor.stopMonitoring(dn1);
     monitor.run();
     assertEquals(0, monitor.getTrackedNodeCount());
-    assertEquals(HddsProtos.NodeOperationalState.IN_SERVICE,
+    assertEquals(IN_SERVICE,
         nodeManager.getNodeStatus(dn1).getOperationalState());
   }
 
@@ -448,10 +451,10 @@ public class TestDatanodeAdminMonitor {
    */
   private ContainerReplicaCount generateReplicaCount(ContainerID containerID,
       HddsProtos.LifeCycleState containerState,
-      ContainerReplicaProto.State... states) {
+      HddsProtos.NodeOperationalState...states) {
     Set<ContainerReplica> replicas = new HashSet<>();
-    for (ContainerReplicaProto.State s : states) {
-      replicas.add(generateReplica(containerID, s));
+    for (HddsProtos.NodeOperationalState s : states) {
+      replicas.add(generateReplica(containerID, s, CLOSED));
     }
     ContainerInfo container = new ContainerInfo.Builder()
         .setContainerID(containerID.getId())
@@ -464,16 +467,20 @@ public class TestDatanodeAdminMonitor {
   /**
    * Generate a new ContainerReplica with the given containerID and State.
    * @param containerID The ID the replica is associated with
-   * @param state The state of the generated replica.
+   * @param nodeState The persistedOpState stored in datanodeDetails.
+   * @param replicaState The state of the generated replica.
    * @return A containerReplica with the given ID and state
    */
   private ContainerReplica generateReplica(ContainerID containerID,
-      ContainerReplicaProto.State state) {
+      HddsProtos.NodeOperationalState nodeState,
+      ContainerReplicaProto.State replicaState) {
+    DatanodeDetails dn = MockDatanodeDetails.randomDatanodeDetails();
+    dn.setPersistedOpState(nodeState);
     return ContainerReplica.newBuilder()
-        .setContainerState(state)
+        .setContainerState(replicaState)
         .setContainerID(containerID)
         .setSequenceId(1)
-        .setDatanodeDetails(MockDatanodeDetails.randomDatanodeDetails())
+        .setDatanodeDetails(dn)
         .build();
   }
 
@@ -500,7 +507,7 @@ public class TestDatanodeAdminMonitor {
    */
   private void mockGetContainerReplicaCount(
       HddsProtos.LifeCycleState containerState,
-      ContainerReplicaProto.State... replicaStates)
+      HddsProtos.NodeOperationalState...replicaStates)
       throws ContainerNotFoundException {
     reset(repManager);
     Mockito.when(repManager.getContainerReplicaCount(


---------------------------------------------------------------------
To unsubscribe, e-mail: ozone-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: ozone-commits-help@hadoop.apache.org