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

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


The following commit(s) were added to refs/heads/master by this push:
     new 05cbe716a12 HDDS-12938. Refactor OneReplicaPipelineSafeModeRule to not 
use PipelineReportFromDatanode (#9464)
05cbe716a12 is described below

commit 05cbe716a126c5e3549059566955e22480357601
Author: Aryan Gupta <[email protected]>
AuthorDate: Fri Feb 20 15:58:40 2026 +0530

    HDDS-12938. Refactor OneReplicaPipelineSafeModeRule to not use 
PipelineReportFromDatanode (#9464)
---
 .../safemode/OneReplicaPipelineSafeModeRule.java   | 28 ++++++++++++++
 .../TestOneReplicaPipelineSafeModeRule.java        | 44 ++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git 
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/safemode/OneReplicaPipelineSafeModeRule.java
 
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/safemode/OneReplicaPipelineSafeModeRule.java
index 4567e0126fc..8b1fc593af3 100644
--- 
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/safemode/OneReplicaPipelineSafeModeRule.java
+++ 
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/safemode/OneReplicaPipelineSafeModeRule.java
@@ -19,7 +19,9 @@
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -85,11 +87,17 @@ protected TypedEvent<PipelineReportFromDatanode> 
getEventType() {
 
   @Override
   protected synchronized boolean validate() {
+    if (!validateBasedOnReportProcessing()) {
+      updateReportedPipelineSet();
+    }
     return currentReportedPipelineCount >= thresholdCount;
   }
 
   @Override
   protected synchronized void process(PipelineReportFromDatanode report) {
+    if (!validateBasedOnReportProcessing()) {
+      return;
+    }
     Objects.requireNonNull(report, "report == null");
     for (PipelineReport report1 : report.getReport().getPipelineReportList()) {
       Pipeline pipeline;
@@ -137,6 +145,10 @@ public synchronized int getCurrentReportedPipelineCount() {
     return currentReportedPipelineCount;
   }
 
+  Set<PipelineID> getReportedPipelineIDSet() {
+    return Collections.unmodifiableSet(reportedPipelineIDSet);
+  }
+
   @Override
   public String getStatusText() {
     String status = String.format(
@@ -171,6 +183,22 @@ public synchronized void refresh(boolean forceRefresh) {
     }
   }
 
+  private void updateReportedPipelineSet() {
+    List<Pipeline> openRatisPipelines =
+        
pipelineManager.getPipelines(RatisReplicationConfig.getInstance(ReplicationFactor.THREE),
+            Pipeline.PipelineState.OPEN);
+
+    for (Pipeline pipeline : openRatisPipelines) {
+      PipelineID pipelineID = pipeline.getId();
+      if (!pipeline.getNodeSet().isEmpty()
+          && oldPipelineIDSet.contains(pipelineID)
+          && reportedPipelineIDSet.add(pipelineID)) {
+        
getSafeModeMetrics().incCurrentHealthyPipelinesWithAtleastOneReplicaReportedCount();
+        currentReportedPipelineCount++;
+      }
+    }
+  }
+
   private void initializeRule(boolean refresh) {
 
     oldPipelineIDSet = pipelineManager.getPipelines(
diff --git 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestOneReplicaPipelineSafeModeRule.java
 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestOneReplicaPipelineSafeModeRule.java
index 2836ec358fb..e83b6e51a93 100644
--- 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestOneReplicaPipelineSafeModeRule.java
+++ 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestOneReplicaPipelineSafeModeRule.java
@@ -18,6 +18,7 @@
 package org.apache.hadoop.hdds.scm.safemode;
 
 import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -30,6 +31,7 @@
 import java.util.Map;
 import org.apache.hadoop.hdds.HddsConfigKeys;
 import org.apache.hadoop.hdds.client.RatisReplicationConfig;
+import org.apache.hadoop.hdds.client.ReplicationConfig;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
@@ -49,6 +51,7 @@
 import org.apache.hadoop.hdds.scm.pipeline.MockRatisPipelineProvider;
 import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
 import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
+import org.apache.hadoop.hdds.scm.pipeline.PipelineManager;
 import org.apache.hadoop.hdds.scm.pipeline.PipelineManagerImpl;
 import org.apache.hadoop.hdds.scm.pipeline.PipelineNotFoundException;
 import org.apache.hadoop.hdds.scm.pipeline.PipelineProvider;
@@ -59,6 +62,7 @@
 import org.apache.ozone.test.TestClock;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.io.TempDir;
+import org.mockito.Mockito;
 
 /**
  * This class tests OneReplicaPipelineSafeModeRule.
@@ -191,6 +195,46 @@ public void testOneReplicaPipelineRuleMixedPipelines() 
throws Exception {
     GenericTestUtils.waitFor(() -> rule.validate(), 1000, 5000);
   }
 
+  @Test
+  public void testOneReplicaPipelineRuleWithReportProcessingFalse() {
+    EventQueue localEventQueue = new EventQueue();
+    PipelineManager mockedPipelineManager = mock(PipelineManager.class);
+    SCMSafeModeManager mockedSafeModeManager = mock(SCMSafeModeManager.class);
+    SafeModeMetrics mockedMetrics = mock(SafeModeMetrics.class);
+    when(mockedSafeModeManager.getSafeModeMetrics()).thenReturn(mockedMetrics);
+
+    OzoneConfiguration conf = new OzoneConfiguration();
+
+    PipelineID pipelineID = PipelineID.randomId();
+    Pipeline mockedPipeline = mock(Pipeline.class);
+    when(mockedPipeline.getId()).thenReturn(pipelineID);
+
+    // First validate(): pipeline has no nodes -> not counted as reported.
+    // Second validate(): pipeline has at least one node -> counted as 
reported.
+    when(mockedPipeline.getNodeSet())
+        .thenReturn(java.util.Collections.emptySet(),
+            new java.util.HashSet<>(
+                
java.util.Collections.singletonList(mock(DatanodeDetails.class))));
+
+    when(mockedPipelineManager.getPipelines(
+        Mockito.any(ReplicationConfig.class),
+        Mockito.eq(Pipeline.PipelineState.OPEN)))
+        .thenReturn(java.util.Collections.singletonList(mockedPipeline));
+
+    OneReplicaPipelineSafeModeRule localRule =
+        new OneReplicaPipelineSafeModeRule(localEventQueue, 
mockedPipelineManager,
+            mockedSafeModeManager, conf);
+
+    localRule.setValidateBasedOnReportProcessing(false);
+
+    // With no nodes in the pipeline, the rule should not be satisfied.
+    assertFalse(localRule.validate());
+
+    // After at least one node is present in the pipeline, the rule should 
pass.
+    assertTrue(localRule.validate());
+    assertTrue(localRule.getReportedPipelineIDSet().contains(pipelineID));
+  }
+
   private void createPipelines(int count,
       HddsProtos.ReplicationFactor factor) throws Exception {
     for (int i = 0; i < count; i++) {


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

Reply via email to