Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-06-05 Thread via GitHub


devmadhuu merged PR #10240:
URL: https://github.com/apache/ozone/pull/10240


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-06-04 Thread via GitHub


chihsuan commented on PR #10240:
URL: https://github.com/apache/ozone/pull/10240#issuecomment-4621142824

   Thanks @priyeshkaratha. 
   
   @devmadhuu Could you please take another look? 🙏 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-20 Thread via GitHub


chihsuan commented on PR #10240:
URL: https://github.com/apache/ozone/pull/10240#issuecomment-4498812708

   @devmadhuu You're right that the SCM sync APIs were the real gap. I've 
pushed three commits addressing all three concerns from the review. Please take 
a look when you get a chance, thanks 🙏 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-20 Thread via GitHub


chihsuan commented on code in PR #10240:
URL: https://github.com/apache/ozone/pull/10240#discussion_r3274159981


##
hadoop-hdds/docs/content/interface/ReconApi.md:
##
@@ -231,26 +239,99 @@ Returns the UnhealthyContainerMetadata objects for all 
the unhealthycontainers.
 ```
 
 ### GET /api/v1/containers/unhealthy/:state
- 
+
 **Parameters**
 
-* batchNum (optional)
- 
-   The batch number (like "page number") of results to return.
-   Passing 1, will return records 1 to limit. 2 will return
-   limit + 1 to 2 * limit, etc.
- 
 * limit (optional)
 
-   Only returns the limited number of results. The default limit is 1000.  
+   Only returns the limited number of results. The default limit is 1000.
+
+* maxContainerId (optional)
+
+   Upper bound for container IDs (exclusive). When specified, returns 
containers with IDs less
+   than this value in descending order. Use it for backward pagination.
+
+* minContainerId (optional)
+
+   Lower bound for container IDs (exclusive). When `maxContainerId` is not 
specified, returns
+   containers with IDs greater than this value in ascending order. Use it for 
forward pagination.
 
 **Returns**
 
 Returns the UnhealthyContainerMetadata objects for the containers in the given 
state.
-Possible unhealthy container states are `MISSING`, 
`MIS_REPLICATED`,`UNDER_REPLICATED`, `OVER_REPLICATED`.
+Possible unhealthy container states are `MISSING`, `MIS_REPLICATED`, 
`UNDER_REPLICATED`, `OVER_REPLICATED`.
 The response structure is same as `/containers/unhealthy`.
 
 
+### GET /api/v1/containers/unhealthy/export
+
+**Returns**
+
+Lists every unhealthy-container export job currently tracked by Recon, in any 
status.
+Items are `ExportJob` objects (see schema below).
+
+```json
+[
+  {
+"jobId": "4f7a8b9c-1234-5678-9abc-def012345678",
+"state": "MISSING",
+"status": "RUNNING",
+"submittedAt": 1718640123456,
+"startedAt": 1718640124000,
+"completedAt": 0,
+"totalRecords": 250,
+"estimatedTotal": 1000,
+"fileName": "",
+"errorMessage": null,
+"progressPercent": 25,
+"queuePosition": 0,
+"downloadCount": 0,
+"downloadsRemaining": 3
+  }
+]
+```
+
+### POST /api/v1/containers/unhealthy/export
+
+**Parameters**
+
+* state (required)
+
+One of `MISSING`, `MIS_REPLICATED`, `UNDER_REPLICATED`, `OVER_REPLICATED`.
+
+**Returns**
+
+Submits a new CSV export job and returns the `ExportJob` with the assigned 
`jobId`.
+The job initially has `status: QUEUED`.
+
+* `400 Bad Request`: `state` is missing or not a valid unhealthy state.
+* `429 Too Many Requests`: the export queue is full; retry later. Body: `{ 
"error": "Too Many Requests", "message": "" }`.
+
+### GET /api/v1/containers/unhealthy/export/:jobId
+
+**Returns**
+
+Returns the current `ExportJob` for the given `jobId`. `404 Not Found` if no 
job has that id.
+
+### GET /api/v1/containers/unhealthy/export/:jobId/download
+
+**Returns**
+
+Streams the TAR archive produced by the export job. Response `Content-Type` is 
`application/x-tar` with
+a `Content-Disposition: attachment` header carrying the export filename.
+
+* `404 Not Found`: `jobId` is unknown or the on-disk file was removed.
+* `409 Conflict`: the job has not reached `COMPLETED` status yet.
+* `429 Too Many Requests`: the per-job download limit has been reached. Body 
matches `RateLimitedError`.

Review Comment:
   Split into two schemas. `RateLimitedError` keeps the "Too Many Requests" 
example for POST `/unhealthy/export`. New `DownloadLimitReachedError` carries 
the "Download limit reached" example download
   
   
https://github.com/apache/ozone/pull/10240/changes/5acb1ea58bf81bff89467653443423dec1340fa7



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-20 Thread via GitHub


chihsuan commented on code in PR #10240:
URL: https://github.com/apache/ozone/pull/10240#discussion_r3274150294


##
hadoop-hdds/docs/content/interface/ReconApi.md:
##
@@ -451,51 +598,126 @@ Returns set of keys/files pending for deletion.
 
 **Returns**
 
-   Returns set of directories pending for deletion.
+Returns the set of directories pending for deletion. Each entry in 
`deletedDirInfo` is a
+`KeyEntityInfo` describing one pending-delete directory (not a 
`RepeatedOmKeyInfo` like
+`/keys/deletePending`).
 
 ```json
 {
-  "lastKey": "vol1/bucket1/bucket1/dir1",
-  "replicatedTotal": -1530804718628866300,
-  "unreplicatedTotal": -1530804718628866300,
-  "deletedkeyinfo": [
+  "lastKey": "/vol1/bucket1/dir1",
+  "replicatedDataSize": 13824,
+  "unreplicatedDataSize": 4608,
+  "deletedDirInfo": [
 {
-  "omKeyInfoList": [
-{
-  "metadata": {},
-  "objectID": 0,
-  "updateID": 0,
-  "parentObjectID": 0,
-  "volumeName": "sampleVol",
-  "bucketName": "bucketOne",
-  "keyName": "key_one",
-  "dataSize": -1530804718628866300,
-  "keyLocationVersions": [],
-  "creationTime": 0,
-  "modificationTime": 0,
-  "replicationConfig": {
-"replicationFactor": "ONE",
-"requiredNodes": 1,
-"replicationType": "STANDALONE"
-  },
-  "fileChecksum": null,
-  "fileName": "key_one",
-  "acls": [],
-  "path": "0/key_one",
-  "file": false,
-  "latestVersionLocations": null,
-  "replicatedSize": -1530804718628866300,
-  "fileEncryptionInfo": null,
-  "objectInfo": "OMKeyInfo{volume='sampleVol', bucket='bucketOne', 
key='key_one', dataSize='-1530804718628866186', creationTime='0', objectID='0', 
parentID='0', replication='STANDALONE/ONE', fileChecksum='null}",
-  "updateIDset": false
-}
-  ]
+  "key": "/-9223372036854775552/-9223372036854774016/dir1",
+  "path": "/vol1/bucket1/dir1",
+  "inStateSince": 17170,
+  "size": 4608,
+  "replicatedSize": 13824,
+  "replicationInfo": {
+"replicationFactor": "THREE",
+"requiredNodes": 3,
+"replicationType": "RATIS"
+  },
+  "creationTime": 17169,
+  "modificationTime": 17169,
+  "isKey": false
 }
   ],
   "status": "OK"
 }
 ```
 
+### GET /api/v1/keys/deletePending/summary
+
+**Returns**
+
+Returns a flat summary of all keys pending deletion across the cluster.
+
+```json
+{
+  "totalDeletedKeys": 8,
+  "totalReplicatedDataSize": 9,
+  "totalUnreplicatedDataSize": 3
+}
+```
+
+### GET /api/v1/keys/deletePending/dirs/summary
+
+**Returns**
+
+Returns the total count of directories pending deletion.
+
+```json
+{
+  "totalDeletedDirectories": 5
+}
+```
+
+### GET /api/v1/keys/listKeys
+
+**Parameters**
+
+* startPrefix (required)

Review Comment:
   Flipped to `required: false` with `default: /` to match 
`@DefaultValue(OM_KEY_PREFIX)`.  
https://github.com/apache/ozone/pull/10240/changes/2952f579b458cf9b28a6b953231ac8eb6b4195bd



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-20 Thread via GitHub


devmadhuu commented on PR #10240:
URL: https://github.com/apache/ozone/pull/10240#issuecomment-4498657004

   For OM sync, it's documented, but I flagged for scm sync API.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-20 Thread via GitHub


chihsuan commented on PR #10240:
URL: https://github.com/apache/ozone/pull/10240#issuecomment-4498640781

   >  thanks for the patch. I think few API docs are missing. Can you kindly 
update ?
   
   Thanks for the review @devmadhuu 🙏  You're right, these are genuinely 
missing. Three of the four landed on master after I cut this branch:
   
   - GET `/containers/quasiClosed` from #10198
   - POST `/triggerdbsync/scm/snapshot`, GET 
`/triggerdbsync/scm/snapshot/status`, POST `/triggerdbsync/scm/snapshot/cancel` 
from #10186
   
   I'll merge master into this branch and document them in the next push, along 
with the inline comments.
   
   (GET `/triggerdbsync/om` is already 
[documented](https://github.com/apache/ozone/pull/10240/changes#diff-4ee2172b726a35d47d7fc513e2734362bd5063ab4213092b72f8e3eebbfcd2dfR1632-R1641)
 in the current PR, Let me know if anything need changes for it.)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-20 Thread via GitHub


chihsuan commented on PR #10240:
URL: https://github.com/apache/ozone/pull/10240#issuecomment-4498594734

   > @chihsuan Thanks for working on this. 
[recon-api.yaml](https://github.com/apache/ozone-site/blob/master/static/recon-api.yaml)
 should be updated.
   
@priyeshkaratha, agreed, it needs the same updates.  I'll file it as a 
follow-up once this PR is merged.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-20 Thread via GitHub


devmadhuu commented on PR #10240:
URL: https://github.com/apache/ozone/pull/10240#issuecomment-4498561808

   > @chihsuan Thanks for working on this. 
[recon-api.yaml](https://github.com/apache/ozone-site/blob/master/static/recon-api.yaml)
 should be updated.
   > 
   > @devmadhuu can we remove recon-api.yaml from ozone project?
   
   @priyeshkaratha , though I agree that , it can be done is separate PR for 
any follow up work, but I think not a good idea to remove the recon-api.yaml 
from ozone project because the file at 
`hadoop-hdds/docs/themes/ozonedoc/static/swagger-resources/recon-api.yaml` is 
actively used by the Hugo docs build: 
[SwaggerReconAPI.md](https://github.com/apache/ozone/blob/066215dbc6f5b94eb4da95020f9207e5e6bb0f56/hadoop-hdds/docs/content/interface/SwaggerReconApi.md)
 seems using.So it should not be removed without first changing 
`SwaggerReconApi.md` to fetch the spec from an external URL (e.g. ozone-site's 
raw GitHub URL), which is a separate and more invasive change. 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-20 Thread via GitHub


devmadhuu commented on code in PR #10240:
URL: https://github.com/apache/ozone/pull/10240#discussion_r3273948666


##
hadoop-hdds/docs/content/interface/ReconApi.md:
##
@@ -451,51 +598,126 @@ Returns set of keys/files pending for deletion.
 
 **Returns**
 
-   Returns set of directories pending for deletion.
+Returns the set of directories pending for deletion. Each entry in 
`deletedDirInfo` is a
+`KeyEntityInfo` describing one pending-delete directory (not a 
`RepeatedOmKeyInfo` like
+`/keys/deletePending`).
 
 ```json
 {
-  "lastKey": "vol1/bucket1/bucket1/dir1",
-  "replicatedTotal": -1530804718628866300,
-  "unreplicatedTotal": -1530804718628866300,
-  "deletedkeyinfo": [
+  "lastKey": "/vol1/bucket1/dir1",
+  "replicatedDataSize": 13824,
+  "unreplicatedDataSize": 4608,
+  "deletedDirInfo": [
 {
-  "omKeyInfoList": [
-{
-  "metadata": {},
-  "objectID": 0,
-  "updateID": 0,
-  "parentObjectID": 0,
-  "volumeName": "sampleVol",
-  "bucketName": "bucketOne",
-  "keyName": "key_one",
-  "dataSize": -1530804718628866300,
-  "keyLocationVersions": [],
-  "creationTime": 0,
-  "modificationTime": 0,
-  "replicationConfig": {
-"replicationFactor": "ONE",
-"requiredNodes": 1,
-"replicationType": "STANDALONE"
-  },
-  "fileChecksum": null,
-  "fileName": "key_one",
-  "acls": [],
-  "path": "0/key_one",
-  "file": false,
-  "latestVersionLocations": null,
-  "replicatedSize": -1530804718628866300,
-  "fileEncryptionInfo": null,
-  "objectInfo": "OMKeyInfo{volume='sampleVol', bucket='bucketOne', 
key='key_one', dataSize='-1530804718628866186', creationTime='0', objectID='0', 
parentID='0', replication='STANDALONE/ONE', fileChecksum='null}",
-  "updateIDset": false
-}
-  ]
+  "key": "/-9223372036854775552/-9223372036854774016/dir1",
+  "path": "/vol1/bucket1/dir1",
+  "inStateSince": 17170,
+  "size": 4608,
+  "replicatedSize": 13824,
+  "replicationInfo": {
+"replicationFactor": "THREE",
+"requiredNodes": 3,
+"replicationType": "RATIS"
+  },
+  "creationTime": 17169,
+  "modificationTime": 17169,
+  "isKey": false
 }
   ],
   "status": "OK"
 }
 ```
 
+### GET /api/v1/keys/deletePending/summary
+
+**Returns**
+
+Returns a flat summary of all keys pending deletion across the cluster.
+
+```json
+{
+  "totalDeletedKeys": 8,
+  "totalReplicatedDataSize": 9,
+  "totalUnreplicatedDataSize": 3
+}
+```
+
+### GET /api/v1/keys/deletePending/dirs/summary
+
+**Returns**
+
+Returns the total count of directories pending deletion.
+
+```json
+{
+  "totalDeletedDirectories": 5
+}
+```
+
+### GET /api/v1/keys/listKeys
+
+**Parameters**
+
+* startPrefix (required)

Review Comment:
   startPrefix marked required: true, but it is actually not. Java uses 
`@DefaultValue(OM_KEY_PREFIX)`, so the parameter has a default at the HTTP 
level.



##
hadoop-hdds/docs/content/interface/ReconApi.md:
##
@@ -231,26 +239,99 @@ Returns the UnhealthyContainerMetadata objects for all 
the unhealthycontainers.
 ```
 
 ### GET /api/v1/containers/unhealthy/:state
- 
+
 **Parameters**
 
-* batchNum (optional)
- 
-   The batch number (like "page number") of results to return.
-   Passing 1, will return records 1 to limit. 2 will return
-   limit + 1 to 2 * limit, etc.
- 
 * limit (optional)
 
-   Only returns the limited number of results. The default limit is 1000.  
+   Only returns the limited number of results. The default limit is 1000.
+
+* maxContainerId (optional)
+
+   Upper bound for container IDs (exclusive). When specified, returns 
containers with IDs less
+   than this value in descending order. Use it for backward pagination.
+
+* minContainerId (optional)
+
+   Lower bound for container IDs (exclusive). When `maxContainerId` is not 
specified, returns
+   containers with IDs greater than this value in ascending order. Use it for 
forward pagination.
 
 **Returns**
 
 Returns the UnhealthyContainerMetadata objects for the containers in the given 
state.
-Possible unhealthy container states are `MISSING`, 
`MIS_REPLICATED`,`UNDER_REPLICATED`, `OVER_REPLICATED`.
+Possible unhealthy container states are `MISSING`, `MIS_REPLICATED`, 
`UNDER_REPLICATED`, `OVER_REPLICATED`.
 The response structure is same as `/containers/unhealthy`.
 
 
+### GET /api/v1/containers/unhealthy/export
+
+**Returns**
+
+Lists every unhealthy-container export job currently tracked by Recon, in any 
status.
+Items are `ExportJob` objects (see schema below).
+
+```json
+[
+  {
+"jobId": "4f7a8b9c-1234-5678-9abc-def012345678",
+"state": "MISSING",
+"status": "RUNNING",
+"submittedAt": 1718640123456,
+"startedAt": 1718640124000,
+"completedAt": 0,
+"totalRecord

Re: [PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-19 Thread via GitHub


priyeshkaratha commented on PR #10240:
URL: https://github.com/apache/ozone/pull/10240#issuecomment-4489460642

   @chihsuan Thanks for working on this. 
   
[recon-api.yaml](https://github.com/apache/ozone-site/blob/master/static/recon-api.yaml)
 should be updated. 
   
   @devmadhuu can we remove recon-api.yaml from ozone project?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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



[PR] HDDS-14643. Update Recon API docs and OpenAPI spec [ozone]

2026-05-11 Thread via GitHub


chihsuan opened a new pull request, #10240:
URL: https://github.com/apache/ozone/pull/10240

   ## Summary
   
   Documentation-only sync of `ReconApi.md` and the in-product Swagger yaml 
against the actual Recon JAX-RS code under 
`hadoop-ozone/recon/src/main/java/.../api/`. No implementation changes. Adds 16 
missing endpoints, fixes 16 existing endpoints' parameters/response examples to 
match the current Java `@JsonProperty` field names and HTTP status behavior, 
and fixes pre-existing structural bugs in the yaml.
   
   ## Why
   
   Both docs had drifted over multiple releases. The yaml had at least one 
schema reference that didn't resolve (`ClusterStorageReport`), several routes 
documented with parameters that no longer exist (`batchNum` on 
`/containers/unhealthy*`), and ~16 routes that exist in Java with no 
documentation. JSON field names in the README examples (`replicatedTotal`, 
`entities`, `deletedkeyinfo`, etc.) did not match the actual `@JsonProperty` 
names serialized by the response DTOs.
   
   ## Endpoint inventory (46 routes total)
   
   | Method | Path | Status | Notes |
   | --- | --- | --- | --- |
   | GET | `/containers` | Updated | Documented existing `prevKey` / `limit` in 
yaml |
   | GET | `/containers/{id}/keys` | Updated | Example refreshed with `lastKey` 
and `CompletePath` |
   | GET | `/containers/{id}/replicaHistory` | Unchanged | |
   | GET | `/containers/missing` | Updated | Marked `@Deprecated` (use 
`/containers/unhealthy/MISSING`) |
   | GET | `/containers/unhealthy` | Updated | `batchNum` removed; documented 
`maxContainerId` / `minContainerId` |
   | GET | `/containers/unhealthy/{state}` | Updated | Same parameter rename |
   | GET | `/containers/unhealthy/export` | Added | List export jobs |
   | POST | `/containers/unhealthy/export` | Added | Submit async CSV export 
job; 400/429 documented |
   | GET | `/containers/unhealthy/export/{jobId}` | Added | Job status |
   | GET | `/containers/unhealthy/export/{jobId}/download` | Added | TAR 
download; 404/409/429 documented |
   | DELETE | `/containers/unhealthy/export/{jobId}` | Added | Cancel job |
   | GET | `/containers/deleted` | Updated | Section added in README (was 
yaml-only) |
   | GET | `/containers/mismatch` | Unchanged | |
   | GET | `/containers/mismatch/deleted` | Unchanged | |
   | GET | `/datanodes` | Updated | Example now includes `opState`, `version`, 
`setupTime`, `revision`, `buildDate`, `layoutVersion`, `networkLocation`, 
`openContainers` |
   | PUT | `/datanodes/remove` | Updated | Corrected to `datanodesResponseMap` 
wrapper with three outcome categories |
   | GET | `/datanodes/decommission/info` | Added | README section (yaml 
already had it) |
   | GET | `/datanodes/decommission/info/datanode` | Added | README section 
(yaml already had it) |
   | GET | `/clusterState` | Updated | Example now includes 
`missingContainers`, `openContainers`, `deletedContainers`, 
`keysPendingDeletion`, `deletedDirs`, `scmServiceId`, `omServiceId`, full 
`storageReport` |
   | GET | `/volumes` | Unchanged | |
   | GET | `/buckets` | Unchanged | |
   | GET | `/keys/open` | Updated | Example uses real field names (`lastKey`, 
`replicatedDataSize`, `fso`, `nonFSO`, `status`); documented `startPrefix`, 
`includeFso`, `includeNonFso` |
   | GET | `/keys/open/summary` | Updated | README section added |
   | GET | `/keys/open/mpu/summary` | Added | Both yaml + README; 
`totalDataSize` (not `totalUnreplicatedDataSize`) is intentional |
   | GET | `/keys/deletePending` | Updated | Example uses `deletedKeyInfo` 
(camelCase) and full `replicatedDataSize`/`unreplicatedDataSize` names; 
`startPrefix` documented |
   | GET | `/keys/deletePending/dirs` | Updated | Example uses `deletedDirInfo` 
(`KeyEntityInfo` shape, not `RepeatedOmKeyInfo`) |
   | GET | `/keys/deletePending/summary` | Updated | README section added |
   | GET | `/keys/deletePending/dirs/summary` | Updated | README section added |
   | GET | `/keys/listKeys` | Added | Both yaml + README; documented 400/503 
responses |
   | GET | `/blocks/deletePending` | Unchanged | |
   | GET | `/namespace/summary` | Unchanged | |
   | GET | `/namespace/usage` | Unchanged | |
   | GET | `/namespace/quota` | Unchanged | |
   | GET | `/namespace/dist` | Unchanged | |
   | GET | `/pipelines` | Unchanged | |
   | GET | `/task/status` | Unchanged | |
   | GET | `/utilization/fileCount` | Unchanged | |
   | GET | `/utilization/containerCount` | Unchanged | |
   | GET | `/metrics/{api}` | Updated | Generalized from yaml's hardcoded 
`/metrics/query` to match Java `@PathParam("api")` |
   | GET | `/storageDistribution` | Added | Backported from `apache/ozone-site` 
and re-verified against Java |
   | GET | `/storageDistribution/download` | Added | Documented 200/202/500 
responses |
   | GET | `/pendingDeletion` | Added | Tri-modal response based on `component` 
(`scm` / `om` / `dn`); 400/204 documented |
   | GET | `/heatmap/readaccess` | Added | 404 documented when featur