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

arafat2198 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 9b713d0b65 HDDS-12395. Add Mismatched Replica tab to the Containers 
Page (#8407)
9b713d0b65 is described below

commit 9b713d0b6594785872090cd78798a0931779f630
Author: Abhishek Pal <pal.abhishek03012...@gmail.com>
AuthorDate: Mon Jul 7 14:02:56 2025 +0530

    HDDS-12395. Add Mismatched Replica tab to the Containers Page (#8407)
---
 .../webapps/recon/ozone-recon-web/api/db.json      | 40 ++++++++++++++++++
 .../src/v2/components/tables/containersTable.tsx   | 48 ++++++++++++++++++----
 .../src/v2/pages/containers/containers.less        | 13 +++++-
 .../src/v2/pages/containers/containers.tsx         | 27 +++++++++++-
 .../src/v2/types/container.types.ts                |  2 +
 5 files changed, 117 insertions(+), 13 deletions(-)

diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json
index 784ee8302e..30fed20bae 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json
@@ -2247,6 +2247,46 @@
             "lastBcsId": 0
           }
         ]
+      },
+      {
+        "containerID": 10,
+        "containerState": "REPLICA_MISMATCH",
+        "unhealthySince": 1665590446222,
+        "expectedReplicaCount": 3,
+        "actualReplicaCount": 3,
+        "replicaDeltaCount": 0,
+        "reason": null,
+        "keys": 1,
+        "pipelineID": "a10ffab6-8ed5-414a-aaf5-79890ff3e8a1",
+        "replicas": [
+          {
+            "containerId": 10,
+            "datanodeUuid": "15526f1b-76f2-4d8f-876c-c343c94ea476",
+            "datanodeHost": "ozone_datanode_2.ozone_overreplicated4",
+            "firstSeenTime": 1665588176660,
+            "lastSeenTime": 1665590397315,
+            "lastBcsId": 2,
+            "dataChecksum": 12345678
+          },
+          {
+            "containerId": 10,
+            "datanodeUuid": "f55476ab-4687-464d-a100-1c65de4366e3",
+            "datanodeHost": "ozone_datanode_3.ozone_overreplicated4",
+            "firstSeenTime": 1665588176616,
+            "lastSeenTime": 1665590392293,
+            "lastBcsId": 2,
+            "dataChecksum": 23456789
+          },
+          {
+            "containerId": 10,
+            "datanodeUuid": "7a457bcb-d63e-49cc-b3ff-8b22bf48d130",
+            "datanodeHost": "ozone_datanode_1.ozone_overreplicated4",
+            "firstSeenTime": 1665588176660,
+            "lastSeenTime": 1665590272289,
+            "lastBcsId": 0,
+            "dataChecksum": 12345678
+          }
+        ]
       }
     ]
   },
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/components/tables/containersTable.tsx
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/components/tables/containersTable.tsx
index a68c9928ee..424d58cf24 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/components/tables/containersTable.tsx
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/components/tables/containersTable.tsx
@@ -18,10 +18,14 @@
 
 import React, {useRef} from 'react';
 import filesize from 'filesize';
-import {AxiosError} from 'axios';
-import {Popover, Table} from 'antd';
-import {ColumnsType, TablePaginationConfig} from 'antd/es/table';
-import {NodeIndexOutlined} from '@ant-design/icons';
+
+import { AxiosError } from 'axios';
+import { Popover, Table } from 'antd';
+import {
+  ColumnsType,
+  TablePaginationConfig
+} from 'antd/es/table';
+import { CheckCircleOutlined, NodeIndexOutlined } from '@ant-design/icons';
 
 import {getFormattedTime} from '@/v2/utils/momentUtils';
 import {showDataFetchError} from '@/utils/common';
@@ -37,6 +41,23 @@ import {
 
 const size = filesize.partial({ standard: 'iec' });
 
+const getDatanodeWith = (idx: number, host: string) => {
+  return (
+    <div key={idx} className='datanode-container-v2-tr'>
+      <NodeIndexOutlined /> {host}
+    </div>
+  );
+}
+
+const getDataNodeWithChecksum = (idx: number, host: string, checksum: string) 
=> {
+  return (
+    <div key={idx} className='datanode-container-v2-tr'>
+      <span className="datanode-container-v2-td"><NodeIndexOutlined /> 
{host}</span>
+      <span className="datanode-container-v2-td">/ {checksum}</span>
+    </div>
+  )
+}
+
 export const COLUMNS: ColumnsType<Container> = [
   {
     title: 'Container ID',
@@ -69,17 +90,26 @@ export const COLUMNS: ColumnsType<Container> = [
     key: 'replicas',
     render: (replicas: ContainerReplica[]) => {
       const renderDatanodes = (replicas: ContainerReplica[]) => {
-        return replicas?.map((replica: any, idx: number) => (
-          <div key={idx} className='datanode-container-v2'>
-            <NodeIndexOutlined /> {replica.datanodeHost}
+        return (
+          <div className="datanode-container-v2-table">
+            {
+              replicas?.map((replica: any, idx: number) => (
+                (replica.dataChecksum)
+                  ? getDataNodeWithChecksum(idx, replica.datanodeHost, 
replica.dataChecksum)
+                  : getDatanodeWith(idx, replica.datanodeHost)
+              ))}
           </div>
-        ))
+        )
       }
 
       return (
         <Popover
           content={renderDatanodes(replicas)}
-          title='Datanodes'
+          title={
+            replicas.some((replica => replica.hasOwnProperty('dataChecksum')))
+            ? 'Datanodes / Checksum'
+            : 'Datanodes'
+          }
           placement='bottomRight'
           trigger='hover'>
           <strong>{replicas.length}</strong> datanodes
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/containers/containers.less
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/containers/containers.less
index f6328ccee6..3f4afc5fc0 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/containers/containers.less
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/containers/containers.less
@@ -45,6 +45,15 @@
   }
 }
 
-.datanode-container-v2 {
- padding: 6px 0px; 
+.datanode-container-v2-table {
+  display: table;
+
+  .datanode-container-v2-tr {
+    display: table-row-group;
+
+    .datanode-container-v2-td {
+      display: table-cell;
+      padding: 2px 4px;
+    }
+  }
 }
\ No newline at end of file
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/containers/containers.tsx
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/containers/containers.tsx
index 78f6424c6e..5cdbdd5262 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/containers/containers.tsx
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/containers/containers.tsx
@@ -64,6 +64,7 @@ const Containers: React.FC<{}> = () => {
     underReplicatedContainerData: [],
     overReplicatedContainerData: [],
     misReplicatedContainerData: [],
+    mismatchedReplicaContainerData: []
   });
   const [expandedRow, setExpandedRow] = useState<ExpandedRow>({});
 
@@ -100,6 +101,9 @@ const Containers: React.FC<{}> = () => {
       const misReplicatedContainerData: Container[] = containers?.filter(
         container => container.containerState === 'MIS_REPLICATED'
       ) ?? [];
+      const mismatchedReplicaContainerData: Container[] = containers?.filter(
+        container => container.containerState === 'REPLICA_MISMATCH'
+      ) ?? [];
 
       setState({
         ...state,
@@ -107,6 +111,7 @@ const Containers: React.FC<{}> = () => {
         underReplicatedContainerData: underReplicatedContainerData,
         overReplicatedContainerData: overReplicatedContainerData,
         misReplicatedContainerData: misReplicatedContainerData,
+        mismatchedReplicaContainerData: mismatchedReplicaContainerData,
         lastUpdated: Number(moment())
       });
       setLoading(false)
@@ -135,7 +140,7 @@ const Containers: React.FC<{}> = () => {
   const {
     lastUpdated, columnOptions,
     missingContainerData, underReplicatedContainerData,
-    overReplicatedContainerData, misReplicatedContainerData
+    overReplicatedContainerData, misReplicatedContainerData, 
mismatchedReplicaContainerData
   } = state;
 
   // Mapping the data to the Tab keys for enabling/disabling search
@@ -143,7 +148,8 @@ const Containers: React.FC<{}> = () => {
     1: missingContainerData,
     2: underReplicatedContainerData,
     3: overReplicatedContainerData,
-    4: misReplicatedContainerData
+    4: misReplicatedContainerData,
+    5: mismatchedReplicaContainerData
   }
 
   const highlightData = (
@@ -168,6 +174,10 @@ const Containers: React.FC<{}> = () => {
         Mis-Replicated <br/>
         <span 
className='highlight-content-value'>{misReplicatedContainerData?.length ?? 
'N/A'}</span>
       </div>
+      <div className='highlight-content'>
+        Mismatched Replicas <br/>
+        <span 
className='highlight-content-value'>{mismatchedReplicaContainerData?.length ?? 
'N/A'}</span>
+      </div>
     </div>
   )
 
@@ -273,6 +283,19 @@ const Containers: React.FC<{}> = () => {
                 expandedRowSetter={setExpandedRow}
               />
             </Tabs.TabPane>
+            <Tabs.TabPane
+              key='5'
+              tab='Mismatched Replicas'>
+              <ContainerTable
+                data={mismatchedReplicaContainerData}
+                loading={loading}
+                searchColumn={searchColumn}
+                searchTerm={debouncedSearch}
+                selectedColumns={selectedColumns}
+                expandedRow={expandedRow}
+                expandedRowSetter={setExpandedRow}
+              />
+            </Tabs.TabPane>
           </Tabs>
         </div>
       </div>
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/types/container.types.ts
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/types/container.types.ts
index 2467a0f26f..85d542ff0c 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/types/container.types.ts
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/types/container.types.ts
@@ -25,6 +25,7 @@ export type ContainerReplica = {
   firstSeenTime: number;
   lastSeenTime: number;
   lastBcsId: number;
+  dataChecksum?: string;
 }
 
 export type Container = {
@@ -91,4 +92,5 @@ export type ContainerState = {
   underReplicatedContainerData: Container[];
   overReplicatedContainerData: Container[];
   misReplicatedContainerData: Container[];
+  mismatchedReplicaContainerData: Container[];
 }
\ No newline at end of file


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

Reply via email to