sumitagrawl commented on code in PR #6969:
URL: https://github.com/apache/ozone/pull/6969#discussion_r1795274085


##########
hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/OMDBInsightEndpoint.java:
##########
@@ -476,17 +426,159 @@ public Response getDeletedKeySummary() {
   @GET
   @Path("/deletePending")
   public Response getDeletedKeyInfo(
-      @DefaultValue(DEFAULT_FETCH_COUNT) @QueryParam(RECON_QUERY_LIMIT)
-      int limit,
-      @DefaultValue(StringUtils.EMPTY) @QueryParam(RECON_QUERY_PREVKEY)
-      String prevKey) {
-    KeyInsightInfoResponse
-        deletedKeyInsightInfo = new KeyInsightInfoResponse();
-    getPendingForDeletionKeyInfo(limit, prevKey,
-        deletedKeyInsightInfo);
+      @DefaultValue(DEFAULT_FETCH_COUNT) @QueryParam(RECON_QUERY_LIMIT) int 
limit,
+      @DefaultValue(StringUtils.EMPTY) @QueryParam(RECON_QUERY_PREVKEY) String 
prevKey,
+      @DefaultValue(StringUtils.EMPTY) @QueryParam(RECON_QUERY_START_PREFIX) 
String startPrefix) {
+
+    // Initialize the response object to hold the key information
+    KeyInsightInfoResponse deletedKeyInsightInfo = new 
KeyInsightInfoResponse();
+
+    // Ensure the limit is non-negative
+    limit = Math.max(0, limit);
+
+    boolean keysFound = false;
+
+    try {
+      if (isNotBlank(startPrefix)) {
+        // Validate and apply prefix-based search
+        if (!validateStartPrefix(startPrefix)) {
+          return createBadRequestResponse("Invalid startPrefix: Path must be 
at the bucket level or deeper.");
+        }
+        keysFound = getPendingForDeletionKeyInfo(limit, prevKey, startPrefix, 
deletedKeyInsightInfo);
+      } else {
+        // Retrieve all records without prefix
+        keysFound = getPendingForDeletionKeyInfo(limit, prevKey, "", 
deletedKeyInsightInfo);
+      }
+    } catch (IllegalArgumentException e) {
+      LOG.debug("Invalid startPrefix provided: {}", startPrefix, e);
+      return createBadRequestResponse("Invalid startPrefix: " + 
e.getMessage());
+    } catch (IOException e) {
+      LOG.debug("I/O error while searching deleted keys in OM DB", e);
+      return createInternalServerErrorResponse("Error searching deleted keys 
in OM DB: " + e.getMessage());
+    } catch (Exception e) {
+      LOG.debug("Unexpected error occurred while searching deleted keys", e);
+      return createInternalServerErrorResponse("Unexpected error: " + 
e.getMessage());
+    }
+
+    if (!keysFound) {
+      return noMatchedKeysResponse("");
+    }
+
     return Response.ok(deletedKeyInsightInfo).build();
   }
 
+  /**
+   * Retrieves keys pending deletion based on startPrefix, filtering keys 
matching the prefix.
+   *
+   * @param limit                 The limit of records to return.
+   * @param prevKey               Pagination key.
+   * @param startPrefix           The search prefix.
+   * @param deletedKeyInsightInfo The response object to populate.
+   */
+  private boolean getPendingForDeletionKeyInfo(
+      int limit, String prevKey, String startPrefix,
+      KeyInsightInfoResponse deletedKeyInsightInfo) throws IOException {
+
+    long replicatedTotal = 0;
+    long unreplicatedTotal = 0;
+    boolean keysFound = false;
+    String lastKey = null;
+
+    // Search for deleted keys in DeletedTable
+    Table<String, RepeatedOmKeyInfo> deletedTable = 
omMetadataManager.getDeletedTable();
+    Map<String, RepeatedOmKeyInfo> deletedKeys =
+        retrieveKeysFromTable(deletedTable, startPrefix, limit, prevKey);
+
+    // Iterate over the retrieved keys and populate the response
+    for (Map.Entry<String, RepeatedOmKeyInfo> entry : deletedKeys.entrySet()) {
+      keysFound = true;
+      RepeatedOmKeyInfo repeatedOmKeyInfo = entry.getValue();
+
+      // We know each RepeatedOmKeyInfo has just one OmKeyInfo object
+      OmKeyInfo keyInfo = repeatedOmKeyInfo.getOmKeyInfoList().get(0);
+      KeyEntityInfo keyEntityInfo = 
createKeyEntityInfoFromOmKeyInfo(entry.getKey(), keyInfo);
+
+      // Add the key directly to the list without classification
+      deletedKeyInsightInfo.getRepeatedOmKeyInfoList().add(repeatedOmKeyInfo);
+
+      replicatedTotal += keyInfo.getReplicatedSize();
+      unreplicatedTotal += keyInfo.getDataSize();
+
+      lastKey = entry.getKey(); // Update lastKey
+    }
+
+    // Set the aggregated totals in the response
+    deletedKeyInsightInfo.setReplicatedDataSize(replicatedTotal);
+    deletedKeyInsightInfo.setUnreplicatedDataSize(unreplicatedTotal);
+    deletedKeyInsightInfo.setLastKey(lastKey);
+
+    return keysFound;
+  }
+
+  /**
+   * Retrieves keys from the specified table based on pagination and prefix 
filtering.
+   * This method handles different scenarios based on the presence of 
startPrefix and prevKey,
+   * enabling efficient key retrieval from the table.
+   *
+   * The method handles the following cases:
+   *
+   * 1. prevKey provided, startPrefix empty:
+   *  - Seeks to prevKey, skips it, and returns subsequent records up to the 
limit.
+   *
+   * 2. prevKey empty, startPrefix empty:
+   *  - Iterates from the beginning of the table, retrieving all records up to 
the limit.
+   *
+   * 3. startPrefix provided, prevKey empty:
+   *  - Seeks to the first key matching startPrefix and returns all matching 
keys up to the limit.
+   *
+   * 4. startPrefix provided, prevKey provided:
+   *  - Seeks to prevKey, skips it, and returns subsequent keys that match 
startPrefix, up to the limit.
+   *
+   * If limit is 0, all matching keys are retrieved. If both startPrefix and 
prevKey are empty, the method starts
+   * from the beginning of the table.
+   */
+  public static <T> Map<String, T> retrieveKeysFromTable(

Review Comment:
   retrieveKeysFromTable  Code can be make similar to one added in 
ReconUtils.java to avoid duplidates



-- 
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]

Reply via email to