From cf6981f3d7a618fc3836c67a26ffa630077559ce Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Fri, 24 May 2024 21:00:04 +0530 Subject: [PATCH 01/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info --- .../webapps/recon/ozone-recon-web/api/db.json | 312 ++++++++++++++---- .../recon/ozone-recon-web/api/routes.json | 4 +- .../src/views/datanodes/datanodes.tsx | 8 +- .../views/datanodes/decommissionSummary.tsx | 119 +++++++ .../src/views/overview/overview.tsx | 22 +- 5 files changed, 401 insertions(+), 64 deletions(-) create mode 100644 hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx 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 79ff9f8e7c6d..f6aabb7b785a 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 @@ -742,55 +742,55 @@ "leaderNode": "localhost1.storage.enterprise.com", "datanodes": [ { - "level": 0, - "parent": null, - "cost": 0, - "uuid": "9e4e92da-4abd-461d-b042-dc4fe72e8727", - "uuidString": "9e4e92da-4abd-461d-b042-dc4fe72e8727", - "ipAddress": "172.22.0.5", - "hostName": "ozone_datanode_1.ozone_default", - "ports": [ - { - "name": "REPLICATION", - "value": 9886 - }, - { - "name": "RATIS", - "value": 9858 - }, - { - "name": "RATIS_ADMIN", - "value": 9857 - }, - { - "name": "RATIS_SERVER", - "value": 9856 - }, - { - "name": "RATIS_DATASTREAM", - "value": 9855 - }, - { - "name": "STANDALONE", - "value": 9859 - } + "level": 0, + "parent": null, + "cost": 0, + "uuid": "9e4e92da-4abd-461d-b042-dc4fe72e8727", + "uuidString": "9e4e92da-4abd-461d-b042-dc4fe72e8727", + "ipAddress": "172.22.0.5", + "hostName": "ozone_datanode_1.ozone_default", + "ports": [ + { + "name": "REPLICATION", + "value": 9886 + }, + { + "name": "RATIS", + "value": 9858 + }, + { + "name": "RATIS_ADMIN", + "value": 9857 + }, + { + "name": "RATIS_SERVER", + "value": 9856 + }, + { + "name": "RATIS_DATASTREAM", + "value": 9855 + }, + { + "name": "STANDALONE", + "value": 9859 + } - ], - "certSerialId": null, - "version": null, - "setupTime": 0, - "revision": null, - "buildDate": null, - "persistedOpState": "IN_SERVICE", - "persistedOpStateExpiryEpochSec": 0, - "initialVersion": 0, - "currentVersion": 1, - "signature": -460136136, - "decomissioned": false, - "networkName": "9e4e92da-4abd-461d-b042-dc4fe72e8727", - "networkLocation": "/default-rack", - "networkFullPath": "/default-rack/9e4e92da-4abd-461d-b042-dc4fe72e8727", - "numOfLeaves": 1 + ], + "certSerialId": null, + "version": null, + "setupTime": 0, + "revision": null, + "buildDate": null, + "persistedOpState": "IN_SERVICE", + "persistedOpStateExpiryEpochSec": 0, + "initialVersion": 0, + "currentVersion": 1, + "signature": -460136136, + "decomissioned": false, + "networkName": "9e4e92da-4abd-461d-b042-dc4fe72e8727", + "networkLocation": "/default-rack", + "networkFullPath": "/default-rack/9e4e92da-4abd-461d-b042-dc4fe72e8727", + "numOfLeaves": 1 } ], "lastLeaderElection": 1578491471528, @@ -3760,9 +3760,9 @@ "totalOpenKeys": 10 }, "keysdeletePendingSummary":{ - "totalUnreplicatedDataSize": 29291, - "totalReplicatedDataSize": 87873, - "totalDeletedKeys": 3 + "totalUnreplicatedDataSize": 29291, + "totalReplicatedDataSize": 87873, + "totalDeletedKeys": 3 }, "omMismatch":{ "containerDiscrepancyInfo": [ @@ -5168,9 +5168,9 @@ }, "nonFSO": { "keysSummary": { - "totalUnreplicatedDataSize": 10485760, - "totalReplicatedDataSize": 31457280, - "totalOpenKeys": 10 + "totalUnreplicatedDataSize": 10485760, + "totalReplicatedDataSize": 31457280, + "totalOpenKeys": 10 }, "nonFSO": [ { @@ -5231,7 +5231,7 @@ "replicationFactor": "ONE", "requiredNodes": 1, "replicationType": "RATIS" - } + } }, { "key": "/-9223372036854775552/-9223372036854775040/-9223372036852420095/2441/110569623850191713", @@ -5243,7 +5243,7 @@ "replicationFactor": "ONE", "requiredNodes": 1, "replicationType": "RATIS" - } + } } ], "status": "OK" @@ -6753,5 +6753,205 @@ } ], "status": "OK" + }, + "decommissioninfo": { + "DatanodesDecommissionInfo":[ + { + "datanodeDetails": { + "level": 3, + "parent": null, + "cost": 0, + "uuid": "4712ba3d-4bb2-477a-9211-d9b50c013055", + "uuidString": "4712ba3d-4bb2-477a-9211-d9b50c013055", + "ipAddress": "172.18.0.13", + "hostName": "ozone-ha-datanode-6.ozone-ha_default", + "ports": [ + { + "name": "HTTP", + "value": 9882 + }, + { + "name": "CLIENT_RPC", + "value": 19864 + }, + { + "name": "REPLICATION", + "value": 9886 + }, + { + "name": "RATIS", + "value": 9858 + }, + { + "name": "RATIS_ADMIN", + "value": 9857 + }, + { + "name": "RATIS_SERVER", + "value": 9856 + }, + { + "name": "RATIS_DATASTREAM", + "value": 9855 + }, + { + "name": "STANDALONE", + "value": 9859 + } + ], + "certSerialId": null, + "version": null, + "setupTime": 0, + "revision": null, + "buildDate": null, + "persistedOpState": "IN_SERVICE", + "persistedOpStateExpiryEpochSec": 0, + "initialVersion": 0, + "currentVersion": 1, + "decommissioned": false, + "maintenance": false, + "ipAddressAsByteString": { + "string": "172.18.0.13", + "bytes": { + "validUtf8": true, + "empty": false + } + }, + "hostNameAsByteString": { + "string": "ozone-ha-datanode-6.ozone-ha_default", + "bytes": { + "validUtf8": true, + "empty": false + } + }, + "networkName": "4712ba3d-4bb2-477a-9211-d9b50c013055", + "networkLocation": "/default-rack", + "networkFullPath": "/default-rack/4712ba3d-4bb2-477a-9211-d9b50c013055", + "numOfLeaves": 1, + "networkNameAsByteString": { + "string": "4712ba3d-4bb2-477a-9211-d9b50c013055", + "bytes": { + "validUtf8": true, + "empty": false + } + }, + "networkLocationAsByteString": { + "string": "/default-rack", + "bytes": { + "validUtf8": true, + "empty": false + } + } + }, + "metrics": null, + "containers": {} + } + ] + }, + "DatanodesDecommissionInfo": { + "DatanodesDecommissionInfo": [ + { + "datanodeDetails": { + "level": 3, + "parent": null, + "cost": 0, + "uuid": "adc72ef9-0850-49d7-935d-e5a4e0d5be3c", + "uuidString": "adc72ef9-0850-49d7-935d-e5a4e0d5be3c", + "ipAddress": "172.18.0.10", + "hostName": "ozone-ha-datanode-2.ozone-ha_default", + "ports": [ + { + "name": "HTTP", + "value": 9882 + }, + { + "name": "CLIENT_RPC", + "value": 19864 + }, + { + "name": "REPLICATION", + "value": 9886 + }, + { + "name": "RATIS", + "value": 9858 + }, + { + "name": "RATIS_ADMIN", + "value": 9857 + }, + { + "name": "RATIS_SERVER", + "value": 9856 + }, + { + "name": "RATIS_DATASTREAM", + "value": 9855 + }, + { + "name": "STANDALONE", + "value": 9859 + } + ], + "certSerialId": null, + "version": null, + "setupTime": 0, + "revision": null, + "buildDate": null, + "persistedOpState": "DECOMMISSIONING", + "persistedOpStateExpiryEpochSec": 0, + "initialVersion": 0, + "currentVersion": 1, + "decommissioned": true, + "maintenance": false, + "ipAddressAsByteString": { + "string": "172.18.0.10", + "bytes": { + "validUtf8": true, + "empty": false + } + }, + "hostNameAsByteString": { + "string": "ozone-ha-datanode-2.ozone-ha_default", + "bytes": { + "validUtf8": true, + "empty": false + } + }, + "networkName": "adc72ef9-0850-49d7-935d-e5a4e0d5be3c", + "networkLocation": "/default-rack", + "networkFullPath": "/default-rack/adc72ef9-0850-49d7-935d-e5a4e0d5be3c", + "numOfLeaves": 1, + "networkNameAsByteString": { + "string": "adc72ef9-0850-49d7-935d-e5a4e0d5be3c", + "bytes": { + "validUtf8": true, + "empty": false + } + }, + "networkLocationAsByteString": { + "string": "/default-rack", + "bytes": { + "validUtf8": true, + "empty": false + } + } + }, + "metrics": { + "decommissionStartTime": "23/05/2024 07:28:35 UTC", + "numOfUnclosedPipelines": 2, + "numOfUnderReplicatedContainers": 0.0, + "numOfUnclosedContainers": 0.0 + }, + "containers": { + "UnderReplicated": [], + "UnClosed": [ + "#6", + "#10", + "#17" + ] + } + } + ] } } \ No newline at end of file diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/routes.json b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/routes.json index 1e1f79d18754..4dd80c906db1 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/routes.json +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/routes.json @@ -49,5 +49,7 @@ "/keys/deletePending?limit=*" : "/keydeletePending", "/containers/mismatch/deleted?limit=*": "/deleted", - "/keys/deletePending/dirs?limit=*": "/dirdeletePending" + "/keys/deletePending/dirs?limit=*": "/dirdeletePending", + "/datanodes/decommission/info": "/decommissioninfo", + "/datanodes/decommission/info/datanode?uuid=*": "/DatanodesDecommissionInfo" } \ No newline at end of file diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx index c42bd8c1f91b..e89f11ab39ad 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx @@ -37,6 +37,7 @@ import {ActionMeta, ValueType} from 'react-select'; import {showDataFetchError} from 'utils/common'; import {ColumnSearch} from 'utils/columnSearch'; import { AxiosGetHelper } from 'utils/axiosRequestHelper'; +import DecommissionSummary from './decommissionSummary'; interface IDatanodeResponse { hostname: string; @@ -163,7 +164,12 @@ const COLUMNS = [ isVisible: true, isSearchable: true, sorter: (a: IDatanode, b: IDatanode) => a.uuid.localeCompare(b.uuid), - defaultSortOrder: 'ascend' as const + defaultSortOrder: 'ascend' as const, + render: (uuid: IDatanode, record: IDatanode) => { + return ( + record.opState === "DECOMMISSIONING" ? : {uuid} + ); + } }, { title: 'Storage Capacity', diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx new file mode 100644 index 000000000000..600b18d172bc --- /dev/null +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { Descriptions, Popover, Tooltip, Icon } from 'antd'; +import { withRouter } from 'react-router-dom'; +import { RouteComponentProps } from 'react-router'; +import axios from 'axios'; +import { showDataFetchError } from 'utils/common'; + +interface IDecommissionSummaryProps extends RouteComponentProps { + uuid: string; + isLoading: boolean; + summaryData: string[]; + record: string[]; +} + +class DecommissionSummary extends React.Component { + constructor(props = {}) { + super(props); + this.state = { + uuid: this.props.uuid, + record: this.props.record, + isLoading: false, + summaryData: [] + }; + } + + componentDidMount(): void { + this.setState({ + isLoading: true + }); + if (this.state.record && this.state.summaryData !== 'null' && this.state.summaryData !== 'undefined') { + this.fetchDecommissionSummary(this.state.uuid); + } + } + + fetchDecommissionSummary = async (selectedUuid: any) => { + try { + const datanodeEndpoint = `/api/v1/datanodes/decommission/info/datanode?uuid=${selectedUuid}`; + let infoDatanodeResponse = await axios.get(datanodeEndpoint); + let DatanodesDecommissionInfo = []; + DatanodesDecommissionInfo = infoDatanodeResponse && infoDatanodeResponse.data && infoDatanodeResponse.data.DatanodesDecommissionInfo[0]; + this.setState({ + loading: false, + summaryData: DatanodesDecommissionInfo + }); + } + catch (error) { + this.setState({ + loading: false, + summaryData: [] + }); + showDataFetchError(error.toString()); + } + }; + + render() { + const { summaryData, uuid } = this.state; + let content; + + if ( summaryData && summaryData.length !== 0 && summaryData !== null && summaryData !== undefined && summaryData.datanodeDetails) { + const { datanodeDetails, containers, metrics } = summaryData; + content = ( + + {datanodeDetails.uuid}   ({datanodeDetails.networkLocation}/{datanodeDetails.ipAddress}/{datanodeDetails.hostname}) + {metrics !== null && metrics !== undefined && Object.keys(metrics).length !== 0 && + <> + {{metrics.decommissionStartTime}} + {{metrics.numOfUnclosedPipelines}} + {{metrics.numOfUnclosedContainers}} + {{metrics.numOfUnderReplicatedContainers}} + + } + { + containers !== null && containers !== undefined && Object.keys(containers).length !== 0 && + <> + {containers.UnderReplicated && containers.UnderReplicated.length > 0 && {containers.UnderReplicated}} + {containers.UnClosed && containers.UnClosed.length > 0 && {containers.UnClosed}} + + } + + ); + } + // Need to check summarydata is not empty + return ( + <> + { (summaryData !== 'null' && summaryData !== 'undefined' && summaryData && summaryData.length !== 0) ? + <> + + + + +  {uuid} + + : uuid + } + + + ); + } +} + +export default withRouter(DecommissionSummary); diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx index a5faa034ecee..390ad52453de 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx @@ -68,6 +68,7 @@ interface IOverviewState { deletePendingSummarytotalUnrepSize: number, deletePendingSummarytotalRepSize: number, deletePendingSummarytotalDeletedKeys: number, + decommissionInfoCount: number } let cancelOverviewSignal: AbortController; @@ -104,7 +105,8 @@ export class Overview extends React.Component, IOverviewS openSummarytotalOpenKeys: 0, deletePendingSummarytotalUnrepSize: 0, deletePendingSummarytotalRepSize: 0, - deletePendingSummarytotalDeletedKeys: 0 + deletePendingSummarytotalDeletedKeys: 0, + decommissionInfoCount: 0 }; this.autoReload = new AutoReloadHelper(this._loadData); } @@ -124,18 +126,21 @@ export class Overview extends React.Component, IOverviewS '/api/v1/clusterState', '/api/v1/task/status', '/api/v1/keys/open/summary', - '/api/v1/keys/deletePending/summary' + '/api/v1/keys/deletePending/summary', + '/api/v1/datanodes/decommission/info' ], cancelOverviewSignal); cancelOverviewSignal = controller; - requests.then(axios.spread((clusterStateResponse, taskstatusResponse, openResponse, deletePendingResponse) => { + requests.then(axios.spread((clusterStateResponse, taskstatusResponse, openResponse, deletePendingResponse, decommissionResponse) => { const clusterState: IClusterStateResponse = clusterStateResponse.data; const taskStatus = taskstatusResponse.data; const missingContainersCount = clusterState.missingContainers; const omDBDeltaObject = taskStatus && taskStatus.find((item:any) => item.taskName === 'OmDeltaRequest'); const omDBFullObject = taskStatus && taskStatus.find((item:any) => item.taskName === 'OmSnapshotRequest'); - + const decommissionInfoCount = decommissionResponse && decommissionResponse.data && + decommissionResponse.data.DatanodesDecommissionInfo && decommissionResponse.data.DatanodesDecommissionInfo.length; + this.setState({ loading: false, datanodes: `${clusterState.healthyDatanodes}/${clusterState.totalDatanodes}`, @@ -156,7 +161,8 @@ export class Overview extends React.Component, IOverviewS openSummarytotalOpenKeys: openResponse.data && openResponse.data.totalOpenKeys, deletePendingSummarytotalUnrepSize: deletePendingResponse.data && deletePendingResponse.data.totalUnreplicatedDataSize, deletePendingSummarytotalRepSize: deletePendingResponse.data && deletePendingResponse.data.totalReplicatedDataSize, - deletePendingSummarytotalDeletedKeys: deletePendingResponse.data && deletePendingResponse.data.totalDeletedKeys + deletePendingSummarytotalDeletedKeys: deletePendingResponse.data && deletePendingResponse.data.totalDeletedKeys, + decommissionInfoCount: decommissionInfoCount ? decommissionInfoCount : 0 }); })).catch(error => { this.setState({ @@ -209,7 +215,7 @@ export class Overview extends React.Component, IOverviewS render() { const {loading, datanodes, pipelines, storageReport, containers, volumes, buckets, openSummarytotalUnrepSize, openSummarytotalRepSize, openSummarytotalOpenKeys, deletePendingSummarytotalUnrepSize,deletePendingSummarytotalRepSize,deletePendingSummarytotalDeletedKeys, - keys, missingContainersCount, lastRefreshed, lastUpdatedOMDBDelta, lastUpdatedOMDBFull, omStatus, openContainers, deletedContainers } = this.state; + keys, missingContainersCount, lastRefreshed, lastUpdatedOMDBDelta, lastUpdatedOMDBFull, omStatus, openContainers, deletedContainers, decommissionInfoCount } = this.state; const datanodesElement = ( @@ -302,6 +308,10 @@ export class Overview extends React.Component, IOverviewS + + + ); From a837686c9bdd9a24a6dd8aafc176616d5e1498b9 Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Wed, 5 Jun 2024 21:58:16 +0530 Subject: [PATCH 02/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info --- .../webapps/recon/ozone-recon-web/api/db.json | 69 +++++++++---------- .../src/views/datanodes/datanodes.tsx | 48 ++++++++++++- .../views/datanodes/decommissionSummary.tsx | 2 +- 3 files changed, 78 insertions(+), 41 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 f6aabb7b785a..8d67b23c51c2 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 @@ -22,7 +22,7 @@ "datanodes": [ { "hostname": "localhost2.storage.enterprise.com", - "uuid": "b590734e-a5f2-11ea-bb37-0242ac130002", + "uuid": "4712ba3d-4bb2-477a-9211-d9b50c013055", "state": "HEALTHY", "opState": "IN_SERVICE", "lastHeartbeat": 1574728876059, @@ -160,7 +160,7 @@ }, { "hostname": "localhost3.storage.enterprise.com", - "uuid": "b5907812-a5f2-11ea-bb37-0242ac130002", + "uuid": "4712ba3d-4bb2-477a-9211-d9b50c013056", "state": "HEALTHY", "opState": "ENTERING_MAINTENANCE", "lastHeartbeat": 1574724876059, @@ -6765,40 +6765,7 @@ "uuidString": "4712ba3d-4bb2-477a-9211-d9b50c013055", "ipAddress": "172.18.0.13", "hostName": "ozone-ha-datanode-6.ozone-ha_default", - "ports": [ - { - "name": "HTTP", - "value": 9882 - }, - { - "name": "CLIENT_RPC", - "value": 19864 - }, - { - "name": "REPLICATION", - "value": 9886 - }, - { - "name": "RATIS", - "value": 9858 - }, - { - "name": "RATIS_ADMIN", - "value": 9857 - }, - { - "name": "RATIS_SERVER", - "value": 9856 - }, - { - "name": "RATIS_DATASTREAM", - "value": 9855 - }, - { - "name": "STANDALONE", - "value": 9859 - } - ], + "certSerialId": null, "version": null, "setupTime": 0, @@ -6845,7 +6812,35 @@ }, "metrics": null, "containers": {} - } + }, + { + "datanodeDetails": { + "level": 3, + "parent": null, + "cost": 0, + "uuid": "4712ba3d-4bb2-477a-9211-d9b50c013056", + "uuidString": "4712ba3d-4bb2-477a-9211-d9b50c013056", + "ipAddress": "172.18.0.13", + "hostName": "ozone-ha-datanode-6.ozone-ha_default", + "certSerialId": null, + "version": null, + "setupTime": 0, + "revision": null, + "buildDate": null, + "persistedOpState": "IN_SERVICE", + "persistedOpStateExpiryEpochSec": 0, + "initialVersion": 0, + "currentVersion": 1, + "decommissioned": false, + "maintenance": false, + "networkName": "4712ba3d-4bb2-477a-9211-d9b50c013055", + "networkLocation": "/default-rack", + "networkFullPath": "/default-rack/4712ba3d-4bb2-477a-9211-d9b50c013055", + "numOfLeaves": 1 + }, + "metrics": null, + "containers": {} + } ] }, "DatanodesDecommissionInfo": { diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx index e89f11ab39ad..3c778921ca10 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx @@ -156,7 +156,6 @@ const COLUMNS = [ render: (text: DatanodeOpState) => renderDatanodeOpState(text), sorter: (a: IDatanode, b: IDatanode) => a.opState.localeCompare(b.opState) }, - { title: 'Uuid', dataIndex: 'uuid', @@ -166,10 +165,22 @@ const COLUMNS = [ sorter: (a: IDatanode, b: IDatanode) => a.uuid.localeCompare(b.uuid), defaultSortOrder: 'ascend' as const, render: (uuid: IDatanode, record: IDatanode) => { + let decommissionToolTip = ( + <> + + +   + {uuid} + + ) return ( - record.opState === "DECOMMISSIONING" ? : {uuid} + // 1.If Info API UUID == Datanodes API UUID then show tooltip As It is going to Decommission Soon + // As It will take time to update datanodes API OP Status to Decommissioning + //2. Once status from datanodes API get changed to Decommissioning show Summary + (decommissionUids && decommissionUids.includes(record.uuid) && (record.opState !== 'DECOMMISSIONING' && record.opState !== 'DECOMMISSIONED')) ? decommissionToolTip : + record.opState === "DECOMMISSIONING" ? : {uuid} ); - } + } }, { title: 'Storage Capacity', @@ -346,6 +357,8 @@ const getTimeDiffFromTimestamp = (timestamp: number): string => { } let cancelSignal: AbortController; +let cancelDecommissionSignal: AbortController; +let decommissionUids: string | string[] =[]; export class Datanodes extends React.Component, IDatanodesState> { autoReload: AutoReloadHelper; @@ -379,6 +392,8 @@ export class Datanodes extends React.Component, IDatanode }; _loadData = () => { + // Need to call decommission API on each interval to get updated status + this._loadDecommisionAPI(); this.setState(prevState => ({ loading: true, selectedColumns: this._getSelectedColumns(prevState.selectedColumns) @@ -423,6 +438,32 @@ export class Datanodes extends React.Component, IDatanode this.setState({ loading: false }); + decommissionUids = []; + showDataFetchError(error.toString()); + }); + + }; + + _loadDecommisionAPI = () => { + this.setState({ + loading: true + }); + + decommissionUids = []; + const { request, controller } = AxiosGetHelper('/api/v1/datanodes/decommission/info', cancelDecommissionSignal); + cancelDecommissionSignal = controller; + request.then(decommissionResponse => { + decommissionUids = decommissionResponse && decommissionResponse.data && + decommissionResponse.data.DatanodesDecommissionInfo && + decommissionResponse.data.DatanodesDecommissionInfo.map((item: { datanodeDetails: { uuid: any; }; }) => item.datanodeDetails.uuid); + this.setState({ + loading: false + }); + }).catch(error => { + this.setState({ + loading: false + }); + decommissionUids = []; showDataFetchError(error.toString()); }); }; @@ -436,6 +477,7 @@ export class Datanodes extends React.Component, IDatanode componentWillUnmount(): void { this.autoReload.stopPolling(); cancelSignal && cancelSignal.abort(); + cancelDecommissionSignal && cancelDecommissionSignal.abort(); } onShowSizeChange = (current: number, pageSize: number) => { diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx index 600b18d172bc..a1c3c47cc139 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx @@ -102,7 +102,7 @@ class DecommissionSummary extends React.Component { <> { (summaryData !== 'null' && summaryData !== 'undefined' && summaryData && summaryData.length !== 0) ? <> - + From e77b8f1990fb01fbfc71a51a3c32eb830c1e59c1 Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Tue, 18 Jun 2024 15:43:53 +0530 Subject: [PATCH 03/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Review COmment --- .../src/views/datanodes/datanodes.tsx | 83 ++++++++++--------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx index 3c778921ca10..aba4b205cd6b 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx @@ -165,20 +165,10 @@ const COLUMNS = [ sorter: (a: IDatanode, b: IDatanode) => a.uuid.localeCompare(b.uuid), defaultSortOrder: 'ascend' as const, render: (uuid: IDatanode, record: IDatanode) => { - let decommissionToolTip = ( - <> - - -   - {uuid} - - ) return ( - // 1.If Info API UUID == Datanodes API UUID then show tooltip As It is going to Decommission Soon - // As It will take time to update datanodes API OP Status to Decommissioning - //2. Once status from datanodes API get changed to Decommissioning show Summary - (decommissionUids && decommissionUids.includes(record.uuid) && (record.opState !== 'DECOMMISSIONING' && record.opState !== 'DECOMMISSIONED')) ? decommissionToolTip : - record.opState === "DECOMMISSIONING" ? : {uuid} + //1. Compare Decommission Api's UUID with all UUID in table and show Decommission Summary + (decommissionUids && decommissionUids.includes(record.uuid) && record.opState !== 'DECOMMISSIONED') ? + : {uuid} ); } }, @@ -359,6 +349,7 @@ const getTimeDiffFromTimestamp = (timestamp: number): string => { let cancelSignal: AbortController; let cancelDecommissionSignal: AbortController; let decommissionUids: string | string[] =[]; +const COLUMN_UPDATE_DECOMMISSIONING = 'DECOMMISSIONING'; export class Datanodes extends React.Component, IDatanodesState> { autoReload: AutoReloadHelper; @@ -391,26 +382,39 @@ export class Datanodes extends React.Component, IDatanode return selectedColumns; }; - _loadData = () => { - // Need to call decommission API on each interval to get updated status - this._loadDecommisionAPI(); - this.setState(prevState => ({ - loading: true, - selectedColumns: this._getSelectedColumns(prevState.selectedColumns) - })); - - const { request, controller } = AxiosGetHelper('/api/v1/datanodes', cancelSignal); - cancelSignal = controller; - request.then(response => { + _loadData = async () => { + // Need to call decommission API on each interval to get updated status before datanode API to compare UUID's + // update Operation State Column in table Manually before rendering + let decommissionAPIRequest = this._loadDecommisionAPI(); + + await decommissionAPIRequest.then(decommissionResponse => { + decommissionUids = decommissionResponse && decommissionResponse.data && + decommissionResponse.data.DatanodesDecommissionInfo && + decommissionResponse.data.DatanodesDecommissionInfo.map((item: { datanodeDetails: { uuid: any; }; }) => item.datanodeDetails.uuid); + this.setState({ + loading: false + }); + }).catch(error => { + this.setState({ + loading: false + }); + decommissionUids = []; + showDataFetchError(error.toString()); + }); + + // Call Datanode API Synchronously after completing Decommission API to render Operation Status Column + let datanodeApiRequest = this._loadDataNodeAPI(); + await datanodeApiRequest.then(response => { const datanodesResponse: IDatanodesResponse = response.data; const totalCount = datanodesResponse.totalCount; const datanodes: IDatanodeResponse[] = datanodesResponse.datanodes; const dataSource: IDatanode[] = datanodes && datanodes.map(datanode => { + let decommissionCondition = decommissionUids && decommissionUids.includes(datanode.uuid) && datanode.opState !== 'DECOMMISSIONED'; return { hostname: datanode.hostname, uuid: datanode.uuid, state: datanode.state, - opState: datanode.opState, + opState: decommissionCondition ? COLUMN_UPDATE_DECOMMISSIONING : datanode.opState, lastHeartbeat: datanode.lastHeartbeat, storageUsed: datanode.storageReport.used, storageTotal: datanode.storageReport.capacity, @@ -444,28 +448,25 @@ export class Datanodes extends React.Component, IDatanode }; - _loadDecommisionAPI = () => { + _loadDecommisionAPI = async () => { this.setState({ loading: true }); decommissionUids = []; - const { request, controller } = AxiosGetHelper('/api/v1/datanodes/decommission/info', cancelDecommissionSignal); + const { request, controller } = await AxiosGetHelper('/api/v1/datanodes/decommission/info', cancelDecommissionSignal); cancelDecommissionSignal = controller; - request.then(decommissionResponse => { - decommissionUids = decommissionResponse && decommissionResponse.data && - decommissionResponse.data.DatanodesDecommissionInfo && - decommissionResponse.data.DatanodesDecommissionInfo.map((item: { datanodeDetails: { uuid: any; }; }) => item.datanodeDetails.uuid); - this.setState({ - loading: false - }); - }).catch(error => { - this.setState({ - loading: false - }); - decommissionUids = []; - showDataFetchError(error.toString()); - }); + return request + }; + + _loadDataNodeAPI = async () => { + this.setState(prevState => ({ + loading: true, + selectedColumns: this._getSelectedColumns(prevState.selectedColumns) + })); + const { request, controller } = await AxiosGetHelper('/api/v1/datanodes', cancelSignal); + cancelSignal = controller; + return request; }; componentDidMount(): void { From b43405c6cce791a4424ff89659cb8a02a993da66 Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Thu, 20 Jun 2024 11:26:15 +0530 Subject: [PATCH 04/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Merge Conflict Solve --- .../ozone-recon-web/src/views/overview/overview.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx index 89664b588f5d..a5591fdde0fd 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx @@ -309,16 +309,14 @@ export class Overview extends React.Component, IOverviewS + + - - - {scmServiceId && @@ -330,6 +328,12 @@ export class Overview extends React.Component, IOverviewS } + + + + + ); } From bc619dd5250ae4e9147b606adf9a3d918f40efb9 Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Wed, 10 Jul 2024 14:03:32 +0530 Subject: [PATCH 05/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info After Merge --- .../recon/ozone-recon-web/src/views/overview/overview.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx index a4d99d952dd7..7b74bfba9661 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx @@ -139,7 +139,6 @@ export class Overview extends React.Component, IOverviewS cancelOverviewSignal = controller; requests.then(axios.spread((clusterStateResponse, taskstatusResponse, openResponse, deletePendingResponse, decommissionResponse) => { - const clusterState: IClusterStateResponse = clusterStateResponse.data; const taskStatus = taskstatusResponse.data; const missingContainersCount = clusterState.missingContainers; @@ -226,7 +225,7 @@ export class Overview extends React.Component, IOverviewS deletePendingSummarytotalUnrepSize, deletePendingSummarytotalRepSize, deletePendingSummarytotalDeletedKeys, keys, missingContainersCount, lastRefreshed, lastUpdatedOMDBDelta, lastUpdatedOMDBFull, omStatus, openContainers, deletedContainers, scmServiceId, omServiceId, decommissionInfoCount } = this.state; - + const datanodesElement = ( {datanodes} HEALTHY From 29906a4f195d16551319c29bb57046c62449e070 Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Wed, 10 Jul 2024 17:28:46 +0530 Subject: [PATCH 06/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info After Merge Conflict --- .../src/views/datanodes/decommissionSummary.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx index a1c3c47cc139..7d5e321c1faa 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx @@ -17,11 +17,12 @@ */ import React from 'react'; -import { Descriptions, Popover, Tooltip, Icon } from 'antd'; +import { Descriptions, Popover, Tooltip } from 'antd'; +import { InfoCircleOutlined } from '@ant-design/icons'; import { withRouter } from 'react-router-dom'; import { RouteComponentProps } from 'react-router'; import axios from 'axios'; -import { showDataFetchError } from 'utils/common'; +import { showDataFetchError } from '@/utils/common'; interface IDecommissionSummaryProps extends RouteComponentProps { uuid: string; @@ -103,7 +104,7 @@ class DecommissionSummary extends React.Component { { (summaryData !== 'null' && summaryData !== 'undefined' && summaryData && summaryData.length !== 0) ? <> - +  {uuid} From bb1241d4568202216c17a92337743857ace80f11 Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Wed, 10 Jul 2024 17:40:19 +0530 Subject: [PATCH 07/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Space issue --- .../webapps/recon/ozone-recon-web/api/db.json | 104 +++++++++--------- 1 file changed, 52 insertions(+), 52 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 27c0f273592c..59d033d24cde 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 @@ -744,55 +744,55 @@ "leaderNode": "localhost1.storage.enterprise.com", "datanodes": [ { - "level": 0, - "parent": null, - "cost": 0, - "uuid": "9e4e92da-4abd-461d-b042-dc4fe72e8727", - "uuidString": "9e4e92da-4abd-461d-b042-dc4fe72e8727", - "ipAddress": "172.22.0.5", - "hostName": "ozone_datanode_1.ozone_default", - "ports": [ - { - "name": "REPLICATION", - "value": 9886 - }, - { - "name": "RATIS", - "value": 9858 - }, - { - "name": "RATIS_ADMIN", - "value": 9857 - }, - { - "name": "RATIS_SERVER", - "value": 9856 - }, - { - "name": "RATIS_DATASTREAM", - "value": 9855 - }, - { - "name": "STANDALONE", - "value": 9859 - } + "level": 0, + "parent": null, + "cost": 0, + "uuid": "9e4e92da-4abd-461d-b042-dc4fe72e8727", + "uuidString": "9e4e92da-4abd-461d-b042-dc4fe72e8727", + "ipAddress": "172.22.0.5", + "hostName": "ozone_datanode_1.ozone_default", + "ports": [ + { + "name": "REPLICATION", + "value": 9886 + }, + { + "name": "RATIS", + "value": 9858 + }, + { + "name": "RATIS_ADMIN", + "value": 9857 + }, + { + "name": "RATIS_SERVER", + "value": 9856 + }, + { + "name": "RATIS_DATASTREAM", + "value": 9855 + }, + { + "name": "STANDALONE", + "value": 9859 + } - ], - "certSerialId": null, - "version": null, - "setupTime": 0, - "revision": null, - "buildDate": null, - "persistedOpState": "IN_SERVICE", - "persistedOpStateExpiryEpochSec": 0, - "initialVersion": 0, - "currentVersion": 1, - "signature": -460136136, - "decomissioned": false, - "networkName": "9e4e92da-4abd-461d-b042-dc4fe72e8727", - "networkLocation": "/default-rack", - "networkFullPath": "/default-rack/9e4e92da-4abd-461d-b042-dc4fe72e8727", - "numOfLeaves": 1 + ], + "certSerialId": null, + "version": null, + "setupTime": 0, + "revision": null, + "buildDate": null, + "persistedOpState": "IN_SERVICE", + "persistedOpStateExpiryEpochSec": 0, + "initialVersion": 0, + "currentVersion": 1, + "signature": -460136136, + "decomissioned": false, + "networkName": "9e4e92da-4abd-461d-b042-dc4fe72e8727", + "networkLocation": "/default-rack", + "networkFullPath": "/default-rack/9e4e92da-4abd-461d-b042-dc4fe72e8727", + "numOfLeaves": 1 } ], "lastLeaderElection": 1578491471528, @@ -3773,10 +3773,10 @@ "totalReplicatedDataSize": 31457280, "totalOpenKeys": 10 }, - "keysdeletePendingSummary":{ - "totalUnreplicatedDataSize": 29291, - "totalReplicatedDataSize": 87873, - "totalDeletedKeys": 3 + "keysdeletePendingSummary": { + "totalUnreplicatedDataSize": 29291, + "totalReplicatedDataSize": 87873, + "totalDeletedKeys": 3 }, "omMismatch": { "containerDiscrepancyInfo": [ From e7a774b5d26acbc00ff2990e48ff3ff6b0c411e5 Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Wed, 10 Jul 2024 17:41:51 +0530 Subject: [PATCH 08/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Space issue --- .../src/main/resources/webapps/recon/ozone-recon-web/api/db.json | 1 - 1 file changed, 1 deletion(-) 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 59d033d24cde..4dc4879d29d5 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 @@ -776,7 +776,6 @@ "name": "STANDALONE", "value": 9859 } - ], "certSerialId": null, "version": null, From c9a9bc19e3d20ddc6b1f5695aca96129ead86a58 Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Wed, 10 Jul 2024 17:55:34 +0530 Subject: [PATCH 09/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Space issue --- .../src/views/overview/overview.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx index 7b74bfba9661..e0e4abde7f2e 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx @@ -67,13 +67,13 @@ interface IOverviewState { omStatus: string; openContainers: number; deletedContainers: number; - openSummarytotalUnrepSize: number, - openSummarytotalRepSize: number, - openSummarytotalOpenKeys: number, - deletePendingSummarytotalUnrepSize: number, - deletePendingSummarytotalRepSize: number, - deletePendingSummarytotalDeletedKeys: number, - decommissionInfoCount: number + openSummarytotalUnrepSize: number; + openSummarytotalRepSize: number; + openSummarytotalOpenKeys: number; + deletePendingSummarytotalUnrepSize: number; + deletePendingSummarytotalRepSize: number; + deletePendingSummarytotalDeletedKeys: number; + decommissionInfoCount: number; scmServiceId: string; omServiceId: string; } From 9c000d7457f4a33e80c60e35230749f4af4c45d7 Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Thu, 11 Jul 2024 12:07:50 +0530 Subject: [PATCH 10/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info --- .../recon/ozone-recon-web/src/views/overview/overview.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx index e0e4abde7f2e..53fe28459ada 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx @@ -327,8 +327,6 @@ export class Overview extends React.Component, IOverviewS } - - From 92eb7a957511b8f6c2ca7fb31b80c3eb432c011b Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Thu, 18 Jul 2024 17:35:58 +0530 Subject: [PATCH 11/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Review Comments --- .../src/views/datanodes/datanodes.tsx | 54 ++++++++++--------- .../src/views/overview/overview.tsx | 2 - 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx index ddd49ececaaa..65c862cdee09 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx @@ -201,7 +201,7 @@ const COLUMNS = [ render: (uuid: IDatanode, record: IDatanode) => { return ( //1. Compare Decommission Api's UUID with all UUID in table and show Decommission Summary - (decommissionUids && decommissionUids.includes(record.uuid) && record.opState !== 'DECOMMISSIONED') ? + (decommissionUuids && decommissionUuids.includes(record.uuid) && record.opState !== 'DECOMMISSIONED') ? : {uuid} ); } @@ -363,7 +363,7 @@ const defaultColumns: IOption[] = COLUMNS.map(column => ({ let cancelSignal: AbortController; let cancelDecommissionSignal: AbortController; -let decommissionUids: string | string[] =[]; +let decommissionUuids: string | string[] =[]; const COLUMN_UPDATE_DECOMMISSIONING = 'DECOMMISSIONING'; export class Datanodes extends React.Component, IDatanodesState> { @@ -401,31 +401,33 @@ export class Datanodes extends React.Component, IDatanode _loadData = async () => { // Need to call decommission API on each interval to get updated status before datanode API to compare UUID's // update Operation State Column in table Manually before rendering - let decommissionAPIRequest = this._loadDecommisionAPI(); - - await decommissionAPIRequest.then(decommissionResponse => { - decommissionUids = decommissionResponse && decommissionResponse.data && - decommissionResponse.data.DatanodesDecommissionInfo && - decommissionResponse.data.DatanodesDecommissionInfo.map((item: { datanodeDetails: { uuid: any; }; }) => item.datanodeDetails.uuid); - this.setState({ - loading: false - }); - }).catch(error => { + try { + let decomissionResponse = await this._loadDecommisionAPI(); + console.log("1=", decomissionResponse); + decommissionUuids = decomissionResponse && decomissionResponse.data && + decomissionResponse.data.DatanodesDecommissionInfo && + decomissionResponse.data.DatanodesDecommissionInfo.map((item: { datanodeDetails: { uuid: any; }; }) => item.datanodeDetails.uuid); + console.log("2=",decommissionUuids); + } + catch (error:any) + { + console.log("catch",error); this.setState({ loading: false }); - decommissionUids = []; + decommissionUuids = []; showDataFetchError(error.toString()); - }); - + } + console.log("3="); + try { // Call Datanode API Synchronously after completing Decommission API to render Operation Status Column - let datanodeApiRequest = this._loadDataNodeAPI(); - await datanodeApiRequest.then(response => { - const datanodesResponse: IDatanodesResponse = response.data; + let datanodeApiResponse = await this._loadDataNodeAPI(); + console.log("4="); + const datanodesResponse: IDatanodesResponse = datanodeApiResponse.data; const totalCount = datanodesResponse.totalCount; const datanodes: IDatanodeResponse[] = datanodesResponse.datanodes; const dataSource: IDatanode[] = datanodes && datanodes.map(datanode => { - let decommissionCondition = decommissionUids && decommissionUids.includes(datanode.uuid) && datanode.opState !== 'DECOMMISSIONED'; + let decommissionCondition = decommissionUuids && decommissionUuids.includes(datanode.uuid) && datanode.opState !== 'DECOMMISSIONED'; return { hostname: datanode.hostname, uuid: datanode.uuid, @@ -447,29 +449,29 @@ export class Datanodes extends React.Component, IDatanode networkLocation: datanode.networkLocation }; }); - + console.log("5"); this.setState({ loading: false, dataSource, totalCount, lastUpdated: Number(moment()) }); - }).catch(error => { + } + catch(error:any) { + console.log("Inside catch2"); this.setState({ loading: false }); - decommissionUids = []; + decommissionUuids = []; showDataFetchError(error.toString()); - }); - + } }; _loadDecommisionAPI = async () => { this.setState({ loading: true }); - - decommissionUids = []; + decommissionUuids = []; const { request, controller } = await AxiosGetHelper('/api/v1/datanodes/decommission/info', cancelDecommissionSignal); cancelDecommissionSignal = controller; return request diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx index 53fe28459ada..f5e6b9b71ccf 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx @@ -309,8 +309,6 @@ export class Overview extends React.Component, IOverviewS - - From ac481d02980b404b9d48f791c6c79f06c03efbff Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Thu, 18 Jul 2024 17:46:33 +0530 Subject: [PATCH 12/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Review Comments Review Changes --- .../ozone-recon-web/src/views/datanodes/datanodes.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx index 65c862cdee09..2f7bac856ff7 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx @@ -403,26 +403,21 @@ export class Datanodes extends React.Component, IDatanode // update Operation State Column in table Manually before rendering try { let decomissionResponse = await this._loadDecommisionAPI(); - console.log("1=", decomissionResponse); decommissionUuids = decomissionResponse && decomissionResponse.data && decomissionResponse.data.DatanodesDecommissionInfo && decomissionResponse.data.DatanodesDecommissionInfo.map((item: { datanodeDetails: { uuid: any; }; }) => item.datanodeDetails.uuid); - console.log("2=",decommissionUuids); } - catch (error:any) + catch (error: any) { - console.log("catch",error); this.setState({ loading: false }); decommissionUuids = []; showDataFetchError(error.toString()); } - console.log("3="); try { // Call Datanode API Synchronously after completing Decommission API to render Operation Status Column let datanodeApiResponse = await this._loadDataNodeAPI(); - console.log("4="); const datanodesResponse: IDatanodesResponse = datanodeApiResponse.data; const totalCount = datanodesResponse.totalCount; const datanodes: IDatanodeResponse[] = datanodesResponse.datanodes; @@ -449,7 +444,6 @@ export class Datanodes extends React.Component, IDatanode networkLocation: datanode.networkLocation }; }); - console.log("5"); this.setState({ loading: false, dataSource, @@ -457,8 +451,7 @@ export class Datanodes extends React.Component, IDatanode lastUpdated: Number(moment()) }); } - catch(error:any) { - console.log("Inside catch2"); + catch (error: any) { this.setState({ loading: false }); From d822239aa62e546ab19c3f151e588817dbf3803e Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Thu, 18 Jul 2024 18:35:51 +0530 Subject: [PATCH 13/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Review Changes --- .../src/components/overviewCard/overviewCard.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/components/overviewCard/overviewCard.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/components/overviewCard/overviewCard.tsx index 93c0cae1f16c..f929efb067af 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/components/overviewCard/overviewCard.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/components/overviewCard/overviewCard.tsx @@ -27,7 +27,8 @@ import { FolderOpenOutlined, FileTextOutlined, QuestionCircleOutlined, - DeleteOutlined + DeleteOutlined, + HourglassOutlined } from '@ant-design/icons'; import { RouteComponentProps } from 'react-router'; import { withRouter, Link } from 'react-router-dom'; @@ -70,7 +71,8 @@ const IconSelector = ({ iconType, ...extras }: { iconType: string }) => { 'inbox': , 'folder-open': , 'file-text': , - 'delete': + 'delete': , + 'hourglass': } const selectIcon = (type: string) => { From 8b82426c1568815fa88079d2ddfec738f7b85dbd Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Wed, 31 Jul 2024 15:10:23 +0530 Subject: [PATCH 14/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Review Comment --- .../src/views/datanodes/decommissionSummary.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx index 7d5e321c1faa..5c5f842e2bdc 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx @@ -78,8 +78,9 @@ class DecommissionSummary extends React.Component { if ( summaryData && summaryData.length !== 0 && summaryData !== null && summaryData !== undefined && summaryData.datanodeDetails) { const { datanodeDetails, containers, metrics } = summaryData; content = ( - - {datanodeDetails.uuid}   ({datanodeDetails.networkLocation}/{datanodeDetails.ipAddress}/{datanodeDetails.hostname}) + + {datanodeDetails.uuid} + ({datanodeDetails.networkLocation}/{datanodeDetails.ipAddress}/{datanodeDetails.hostname}) {metrics !== null && metrics !== undefined && Object.keys(metrics).length !== 0 && <> {{metrics.decommissionStartTime}} @@ -91,8 +92,8 @@ class DecommissionSummary extends React.Component { { containers !== null && containers !== undefined && Object.keys(containers).length !== 0 && <> - {containers.UnderReplicated && containers.UnderReplicated.length > 0 && {containers.UnderReplicated}} - {containers.UnClosed && containers.UnClosed.length > 0 && {containers.UnClosed}} + {containers.UnderReplicated && containers.UnderReplicated.length > 0 && {containers.UnderReplicated}} + {containers.UnClosed && containers.UnClosed.length > 0 && {containers.UnClosed}} } @@ -106,7 +107,7 @@ class DecommissionSummary extends React.Component { - +  {uuid} : uuid From 3e08fb7b48adea2a78e0f77408427da00db453bf Mon Sep 17 00:00:00 2001 From: smitajoshi12 Date: Mon, 5 Aug 2024 15:14:00 +0530 Subject: [PATCH 15/15] HDDS-10517. Recon - Add a UI component for showing DN decommissioning detailed status and info Review Comment --- .../src/views/datanodes/datanodes.tsx | 12 +++++++++--- .../src/views/datanodes/decommissionSummary.tsx | 8 ++++---- .../ozone-recon-web/src/views/overview/overview.tsx | 3 +-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx index 2f7bac856ff7..47fe41dd7b31 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/datanodes.tsx @@ -366,6 +366,14 @@ let cancelDecommissionSignal: AbortController; let decommissionUuids: string | string[] =[]; const COLUMN_UPDATE_DECOMMISSIONING = 'DECOMMISSIONING'; +type DatanodeDetails = { + uuid: string; +} + +type DatanodeDecomissionInfo = { +datanodeDetails: DatanodeDetails +} + export class Datanodes extends React.Component, IDatanodesState> { autoReload: AutoReloadHelper; @@ -403,9 +411,7 @@ export class Datanodes extends React.Component, IDatanode // update Operation State Column in table Manually before rendering try { let decomissionResponse = await this._loadDecommisionAPI(); - decommissionUuids = decomissionResponse && decomissionResponse.data && - decomissionResponse.data.DatanodesDecommissionInfo && - decomissionResponse.data.DatanodesDecommissionInfo.map((item: { datanodeDetails: { uuid: any; }; }) => item.datanodeDetails.uuid); + decommissionUuids = decomissionResponse.data?.DatanodesDecommissionInfo?.map((item: DatanodeDecomissionInfo) => item.datanodeDetails.uuid); } catch (error: any) { diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx index 5c5f842e2bdc..28527c0816e0 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/datanodes/decommissionSummary.tsx @@ -46,7 +46,7 @@ class DecommissionSummary extends React.Component { this.setState({ isLoading: true }); - if (this.state.record && this.state.summaryData !== 'null' && this.state.summaryData !== 'undefined') { + if (this.state?.record && this.state?.summaryData) { this.fetchDecommissionSummary(this.state.uuid); } } @@ -56,7 +56,7 @@ class DecommissionSummary extends React.Component { const datanodeEndpoint = `/api/v1/datanodes/decommission/info/datanode?uuid=${selectedUuid}`; let infoDatanodeResponse = await axios.get(datanodeEndpoint); let DatanodesDecommissionInfo = []; - DatanodesDecommissionInfo = infoDatanodeResponse && infoDatanodeResponse.data && infoDatanodeResponse.data.DatanodesDecommissionInfo[0]; + DatanodesDecommissionInfo = infoDatanodeResponse?.data?.DatanodesDecommissionInfo[0]; this.setState({ loading: false, summaryData: DatanodesDecommissionInfo @@ -90,7 +90,7 @@ class DecommissionSummary extends React.Component { } { - containers !== null && containers !== undefined && Object.keys(containers).length !== 0 && + containers && Object.keys(containers).length !== 0 && <> {containers.UnderReplicated && containers.UnderReplicated.length > 0 && {containers.UnderReplicated}} {containers.UnClosed && containers.UnClosed.length > 0 && {containers.UnClosed}} @@ -102,7 +102,7 @@ class DecommissionSummary extends React.Component { // Need to check summarydata is not empty return ( <> - { (summaryData !== 'null' && summaryData !== 'undefined' && summaryData && summaryData.length !== 0) ? + { (summaryData && summaryData.length !== 0) ? <> diff --git a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx index 55acdc55cf77..a83d12408b3a 100644 --- a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx +++ b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/overview/overview.tsx @@ -288,8 +288,7 @@ export class Overview extends React.Component, IOverviewS openKeysError = true; } - if ([ - decommissionInfoCount].some( + if ([decommissionInfoCount].some( (data) => data === undefined )) { decommissionInfoError = true;