This is an automated email from the ASF dual-hosted git repository.
devesh 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 29ff00a8f56 HDDS-14368. Recon showing wrong pipelines for containers.
(#9707)
29ff00a8f56 is described below
commit 29ff00a8f56d97e039009a065a49cd4abd68cde6
Author: Devesh Kumar Singh <[email protected]>
AuthorDate: Thu Feb 5 09:20:38 2026 +0530
HDDS-14368. Recon showing wrong pipelines for containers. (#9707)
---
.../hadoop/ozone/recon/api/ContainerEndpoint.java | 2 +-
.../ozone/recon/api/TestContainerEndpoint.java | 98 ++++++++++++++++++++++
2 files changed, 99 insertions(+), 1 deletion(-)
diff --git
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/ContainerEndpoint.java
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/ContainerEndpoint.java
index 49fab38fcf2..c1818b84fae 100644
---
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/ContainerEndpoint.java
+++
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/ContainerEndpoint.java
@@ -659,11 +659,11 @@ public Response getContainerMisMatchInsights(
}
}
- List<Pipeline> pipelines = new ArrayList<>();
nonOMContainers.forEach(containerInfo -> {
ContainerDiscrepancyInfo containerDiscrepancyInfo = new
ContainerDiscrepancyInfo();
containerDiscrepancyInfo.setContainerID(containerInfo.getContainerID());
containerDiscrepancyInfo.setNumberOfKeys(0);
+ List<Pipeline> pipelines = new ArrayList<>();
PipelineID pipelineID = null;
try {
pipelineID = containerInfo.getPipelineID();
diff --git
a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestContainerEndpoint.java
b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestContainerEndpoint.java
index 3b0764ba3fc..19f1593db66 100644
---
a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestContainerEndpoint.java
+++
b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestContainerEndpoint.java
@@ -26,8 +26,10 @@
import static
org.apache.hadoop.ozone.recon.OMMetadataManagerTestUtils.writeKeyToOm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -1596,6 +1598,102 @@ public void testContainerMissingFilter()
assertThat(missingContainerIdsSCM).contains(2L);
}
+ /**
+ * Helper to create a container in SCM with a specific pipeline.
+ */
+ private void createContainerInSCM(long containerId, Pipeline targetPipeline)
+ throws IOException, TimeoutException {
+ ContainerInfo containerInfo = new ContainerInfo.Builder()
+ .setContainerID(containerId)
+ .setReplicationConfig(
+ RatisReplicationConfig.getInstance(ReplicationFactor.THREE))
+ .setState(HddsProtos.LifeCycleState.OPEN)
+ .setOwner("owner" + containerId)
+ .setNumberOfKeys(0)
+ .setPipelineID(targetPipeline.getId())
+ .build();
+ reconContainerManager.addNewContainer(
+ new ContainerWithPipeline(containerInfo, targetPipeline));
+ }
+
+ /**
+ * Helper to verify pipeline isolation for a container missing in OM.
+ */
+ private void verifyPipelineIsolation(ContainerDiscrepancyInfo info,
+ long containerId, PipelineID expectedPipelineId,
+ List<List<Pipeline>> otherPipelineLists) {
+ List<Pipeline> pipelines = info.getPipelines();
+ assertNotNull(pipelines);
+ assertEquals(1, pipelines.size(),
+ "Container " + containerId + " should have exactly 1 pipeline");
+ assertEquals(expectedPipelineId, pipelines.get(0).getId(),
+ "Container " + containerId + " should have correct pipeline");
+ assertEquals("SCM", info.getExistsAt());
+ assertEquals(0, info.getNumberOfKeys());
+ // Verify list isolation
+ for (List<Pipeline> other : otherPipelineLists) {
+ if (other != null) {
+ assertNotSame(pipelines, other,
+ "Container " + containerId + " should have independent list");
+ }
+ }
+ }
+
+ @Test
+ public void testGetContainerInsightsNonOMContainersPipelineIsolation()
+ throws IOException, TimeoutException {
+ // Verifies fix for pipeline accumulation bug: containers missing in OM
+ // should each have their own isolated pipeline list, not shared.
+
+ // Create 3 different pipelines
+ Pipeline[] pipelines = {
+ getRandomPipeline(), getRandomPipeline(), getRandomPipeline()
+ };
+ for (Pipeline p : pipelines) {
+ reconPipelineManager.addPipeline(p);
+ }
+
+ // Create 3 containers in SCM with different pipelines (not in OM)
+ long[] containerIds = {501L, 502L, 503L};
+ for (int i = 0; i < containerIds.length; i++) {
+ createContainerInSCM(containerIds[i], pipelines[i]);
+
assertFalse(reconContainerMetadataManager.doesContainerExists(containerIds[i]),
+ "Container " + containerIds[i] + " should NOT exist in OM");
+ }
+
+ // Call API
+ Response response = containerEndpoint.getContainerMisMatchInsights(10,
500, "OM");
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+ Map<String, Object> responseMap = (Map<String, Object>)
response.getEntity();
+ List<ContainerDiscrepancyInfo> discrepancies =
+ (List<ContainerDiscrepancyInfo>)
responseMap.get("containerDiscrepancyInfo");
+ assertNotNull(discrepancies);
+
+ // Find containers in response
+ ContainerDiscrepancyInfo[] infos = new ContainerDiscrepancyInfo[3];
+ for (int i = 0; i < containerIds.length; i++) {
+ final long id = containerIds[i];
+ infos[i] = discrepancies.stream()
+ .filter(d -> d.getContainerID() == id)
+ .findFirst()
+ .orElseThrow(() -> new AssertionError(
+ "Container " + id + " not found in mismatch list"));
+ }
+
+ // Verify pipeline isolation for each container
+ List<Pipeline> pipelineList1 = infos[0].getPipelines();
+ List<Pipeline> pipelineList2 = infos[1].getPipelines();
+ List<Pipeline> pipelineList3 = infos[2].getPipelines();
+
+ verifyPipelineIsolation(infos[0], containerIds[0], pipelines[0].getId(),
+ Arrays.asList(pipelineList2, pipelineList3));
+ verifyPipelineIsolation(infos[1], containerIds[1], pipelines[1].getId(),
+ Arrays.asList(pipelineList1, pipelineList3));
+ verifyPipelineIsolation(infos[2], containerIds[2], pipelines[2].getId(),
+ Arrays.asList(pipelineList1, pipelineList2));
+ }
+
@Test
public void testGetOmContainersDeletedInSCM() throws Exception {
Map<Long, ContainerMetadata> omContainers =
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]