entry : deletedKeys.entrySet()) {
@@ -1265,8 +1295,7 @@ private KeyEntityInfo createKeyEntityInfoFromOmKeyInfo(String dbKey,
KeyEntityInfo keyEntityInfo = new KeyEntityInfo();
keyEntityInfo.setKey(dbKey); // Set the DB key
keyEntityInfo.setIsKey(keyInfo.isFile());
- keyEntityInfo.setPath(ReconUtils.constructFullPath(keyInfo, reconNamespaceSummaryManager,
- omMetadataManager));
+ keyEntityInfo.setPath(ReconUtils.constructFullPath(keyInfo, reconNamespaceSummaryManager, omMetadataManager));
keyEntityInfo.setSize(keyInfo.getDataSize());
keyEntityInfo.setCreationTime(keyInfo.getCreationTime());
keyEntityInfo.setModificationTime(keyInfo.getModificationTime());
@@ -1284,6 +1313,20 @@ private void createSummaryForDeletedDirectories(
dirSummary.put("totalDeletedDirectories", deletedDirCount);
}
+ private boolean validateStartPrefix(String startPrefix) {
+
+ // Ensure startPrefix starts with '/' for non-empty values
+ startPrefix = startPrefix.startsWith("/") ? startPrefix : "/" + startPrefix;
+
+ // Split the path to ensure it's at least at the bucket level (volume/bucket).
+ String[] pathComponents = startPrefix.split("/");
+ if (pathComponents.length < 3 || pathComponents[2].isEmpty()) {
+ return false; // Invalid if not at bucket level or deeper
+ }
+
+ return true;
+ }
+
private String createPath(OmKeyInfo omKeyInfo) {
return omKeyInfo.getVolumeName() + OM_KEY_PREFIX +
omKeyInfo.getBucketName() + OM_KEY_PREFIX + omKeyInfo.getKeyName();
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/OMDBInsightSearchEndpoint.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/OMDBInsightSearchEndpoint.java
deleted file mode 100644
index fcd73fbe72f2..000000000000
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/OMDBInsightSearchEndpoint.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.hadoop.ozone.recon.api;
-
-import org.apache.hadoop.hdds.scm.server.OzoneStorageContainerManager;
-import org.apache.hadoop.hdds.utils.db.Table;
-import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
-import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
-import org.apache.hadoop.ozone.om.helpers.BucketLayout;
-import org.apache.hadoop.ozone.recon.api.handlers.BucketHandler;
-import org.apache.hadoop.ozone.recon.api.types.KeyEntityInfo;
-import org.apache.hadoop.ozone.recon.api.types.KeyInsightInfoResponse;
-import org.apache.hadoop.ozone.recon.api.types.NSSummary;
-import org.apache.hadoop.ozone.recon.recovery.ReconOMMetadataManager;
-import org.apache.hadoop.ozone.recon.spi.impl.ReconNamespaceSummaryManagerImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.io.IOException;
-import java.util.Map;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.ArrayList;
-
-import static org.apache.hadoop.ozone.OzoneConsts.OM_KEY_PREFIX;
-import static org.apache.hadoop.ozone.recon.ReconConstants.RECON_OM_INSIGHTS_DEFAULT_START_PREFIX;
-import static org.apache.hadoop.ozone.recon.ReconConstants.RECON_OM_INSIGHTS_DEFAULT_SEARCH_LIMIT;
-import static org.apache.hadoop.ozone.recon.ReconConstants.RECON_OM_INSIGHTS_DEFAULT_SEARCH_PREV_KEY;
-import static org.apache.hadoop.ozone.recon.ReconResponseUtils.noMatchedKeysResponse;
-import static org.apache.hadoop.ozone.recon.ReconResponseUtils.createBadRequestResponse;
-import static org.apache.hadoop.ozone.recon.ReconResponseUtils.createInternalServerErrorResponse;
-import static org.apache.hadoop.ozone.recon.ReconUtils.validateStartPrefix;
-import static org.apache.hadoop.ozone.recon.ReconUtils.constructObjectPathWithPrefix;
-import static org.apache.hadoop.ozone.recon.ReconUtils.extractKeysFromTable;
-import static org.apache.hadoop.ozone.recon.ReconUtils.gatherSubPaths;
-import static org.apache.hadoop.ozone.recon.ReconUtils.validateNames;
-import static org.apache.hadoop.ozone.recon.api.handlers.BucketHandler.getBucketHandler;
-import static org.apache.hadoop.ozone.recon.api.handlers.EntityHandler.normalizePath;
-import static org.apache.hadoop.ozone.recon.api.handlers.EntityHandler.parseRequestPath;
-
-/**
- * REST endpoint for search implementation in OM DB Insight.
- *
- * This class provides endpoints for searching keys in the Ozone Manager database.
- * It supports searching for both open and deleted keys across File System Optimized (FSO)
- * and Object Store (non-FSO) bucket layouts. The results include matching keys and their
- * data sizes.
- */
-@Path("/keys")
-@Produces(MediaType.APPLICATION_JSON)
-@AdminOnly
-public class OMDBInsightSearchEndpoint {
-
- private OzoneStorageContainerManager reconSCM;
- private final ReconOMMetadataManager omMetadataManager;
- private static final Logger LOG =
- LoggerFactory.getLogger(OMDBInsightSearchEndpoint.class);
- private ReconNamespaceSummaryManagerImpl reconNamespaceSummaryManager;
-
-
- @Inject
- public OMDBInsightSearchEndpoint(OzoneStorageContainerManager reconSCM,
- ReconOMMetadataManager omMetadataManager,
- ReconNamespaceSummaryManagerImpl reconNamespaceSummaryManager) {
- this.reconSCM = reconSCM;
- this.omMetadataManager = omMetadataManager;
- this.reconNamespaceSummaryManager = reconNamespaceSummaryManager;
- }
-
-
- /**
- * Performs a search for open keys in the Ozone Manager OpenKey and OpenFile table using a specified search prefix.
- * This endpoint searches across both File System Optimized (FSO) and Object Store (non-FSO) layouts,
- * compiling a list of keys that match the given prefix along with their data sizes.
- *
- * The search prefix must start from the bucket level ('/volumeName/bucketName/') or any specific directory
- * or key level (e.g., '/volA/bucketA/dir1' for everything under 'dir1' inside 'bucketA' of 'volA').
- * The search operation matches the prefix against the start of keys' names within the OM DB.
- *
- * Example Usage:
- * 1. A startPrefix of "/volA/bucketA/" retrieves every key under bucket 'bucketA' in volume 'volA'.
- * 2. Specifying "/volA/bucketA/dir1" focuses the search within 'dir1' inside 'bucketA' of 'volA'.
- *
- * @param startPrefix The prefix for searching keys, starting from the bucket level or any specific path.
- * @param limit Limits the number of returned keys.
- * @param prevKey The key to start after for the next set of records.
- * @return A KeyInsightInfoResponse, containing matching keys and their data sizes.
- * @throws IOException On failure to access the OM database or process the operation.
- * @throws IllegalArgumentException If the provided startPrefix or other arguments are invalid.
- */
- @GET
- @Path("/open/search")
- public Response searchOpenKeys(
- @DefaultValue(RECON_OM_INSIGHTS_DEFAULT_START_PREFIX) @QueryParam("startPrefix")
- String startPrefix,
- @DefaultValue(RECON_OM_INSIGHTS_DEFAULT_SEARCH_LIMIT) @QueryParam("limit")
- int limit,
- @DefaultValue(RECON_OM_INSIGHTS_DEFAULT_SEARCH_PREV_KEY) @QueryParam("prevKey")
- String prevKey) throws IOException {
-
- try {
- // Validate the request parameters
- if (!validateStartPrefix(startPrefix)) {
- return createBadRequestResponse("Invalid startPrefix: Path must be at the bucket level or deeper.");
- }
-
- // Ensure the limit is non-negative
- limit = Math.max(0, limit);
-
- // Initialize response object
- KeyInsightInfoResponse insightResponse = new KeyInsightInfoResponse();
- long replicatedTotal = 0;
- long unreplicatedTotal = 0;
- boolean keysFound = false; // Flag to track if any keys are found
- String lastKey = null;
-
- // Search for non-fso keys in KeyTable
- Table openKeyTable =
- omMetadataManager.getOpenKeyTable(BucketLayout.LEGACY);
- Map obsKeys =
- extractKeysFromTable(openKeyTable, startPrefix, limit, prevKey);
- for (Map.Entry entry : obsKeys.entrySet()) {
- keysFound = true;
- KeyEntityInfo keyEntityInfo =
- createKeyEntityInfoFromOmKeyInfo(entry.getKey(), entry.getValue());
- insightResponse.getNonFSOKeyInfoList()
- .add(keyEntityInfo); // Add to non-FSO list
- replicatedTotal += entry.getValue().getReplicatedSize();
- unreplicatedTotal += entry.getValue().getDataSize();
- lastKey = entry.getKey(); // Update lastKey
- }
-
- // Search for fso keys in FileTable
- Map fsoKeys = searchOpenKeysInFSO(startPrefix, limit, prevKey);
- for (Map.Entry entry : fsoKeys.entrySet()) {
- keysFound = true;
- KeyEntityInfo keyEntityInfo =
- createKeyEntityInfoFromOmKeyInfo(entry.getKey(), entry.getValue());
- insightResponse.getFsoKeyInfoList()
- .add(keyEntityInfo); // Add to FSO list
- replicatedTotal += entry.getValue().getReplicatedSize();
- unreplicatedTotal += entry.getValue().getDataSize();
- lastKey = entry.getKey(); // Update lastKey
- }
-
- // If no keys were found, return a response indicating that no keys matched
- if (!keysFound) {
- return noMatchedKeysResponse(startPrefix);
- }
-
- // Set the aggregated totals in the response
- insightResponse.setReplicatedDataSize(replicatedTotal);
- insightResponse.setUnreplicatedDataSize(unreplicatedTotal);
- insightResponse.setLastKey(lastKey);
-
- // Return the response with the matched keys and their data sizes
- return Response.ok(insightResponse).build();
- } catch (IOException e) {
- // Handle IO exceptions and return an internal server error response
- return createInternalServerErrorResponse(
- "Error searching open keys in OM DB: " + e.getMessage());
- } catch (IllegalArgumentException e) {
- // Handle illegal argument exceptions and return a bad request response
- return createBadRequestResponse(
- "Invalid startPrefix: " + e.getMessage());
- }
- }
-
- public Map searchOpenKeysInFSO(String startPrefix,
- int limit, String prevKey)
- throws IOException, IllegalArgumentException {
- Map matchedKeys = new LinkedHashMap<>();
- // Convert the search prefix to an object path for FSO buckets
- String startPrefixObjectPath = convertToObjectPath(startPrefix);
- String[] names = parseRequestPath(startPrefixObjectPath);
- Table openFileTable =
- omMetadataManager.getOpenKeyTable(BucketLayout.FILE_SYSTEM_OPTIMIZED);
-
- // If names.length <= 2, then the search prefix is at the volume or bucket level hence
- // no need to find parent or extract id's or find subpaths as the openFileTable is
- // suitable for volume and bucket level search
- if (names.length > 2 && startPrefixObjectPath.endsWith(OM_KEY_PREFIX)) {
- // Fetch the parent ID to search for
- long parentId = Long.parseLong(names[names.length - 1]);
-
- // Fetch the nameSpaceSummary for the parent ID
- NSSummary parentSummary = reconNamespaceSummaryManager.getNSSummary(parentId);
- if (parentSummary == null) {
- return matchedKeys;
- }
- List subPaths = new ArrayList<>();
- // Add the initial search prefix object path because it can have both openFiles
- // and subdirectories with openFiles
- subPaths.add(startPrefixObjectPath);
-
- // Recursively gather all subpaths
- gatherSubPaths(parentId, subPaths, Long.parseLong(names[0]), Long.parseLong(names[1]),
- reconNamespaceSummaryManager);
-
- // Iterate over the subpaths and retrieve the open files
- for (String subPath : subPaths) {
- matchedKeys.putAll(
- extractKeysFromTable(openFileTable, subPath, limit - matchedKeys.size(), prevKey));
- if (matchedKeys.size() >= limit) {
- break;
- }
- }
- return matchedKeys;
- }
-
- // If the search level is at the volume, bucket or key level, directly search the openFileTable
- matchedKeys.putAll(
- extractKeysFromTable(openFileTable, startPrefixObjectPath, limit, prevKey));
- return matchedKeys;
- }
-
- /**
- * Converts a key prefix into an object path for FSO buckets, using IDs.
- *
- * This method transforms a user-provided path (e.g., "volume/bucket/dir1") into
- * a database-friendly format ("/volumeID/bucketID/ParentId/") by replacing names
- * with their corresponding IDs. It simplifies database queries for FSO bucket operations.
- *
- * {@code
- * Examples:
- * - Input: "volume/bucket/key" -> Output: "/volumeID/bucketID/parentDirID/key"
- * - Input: "volume/bucket/dir1" -> Output: "/volumeID/bucketID/dir1ID/"
- * - Input: "volume/bucket/dir1/key1" -> Output: "/volumeID/bucketID/dir1ID/key1"
- * - Input: "volume/bucket/dir1/dir2" -> Output: "/volumeID/bucketID/dir2ID/"
- * }
- *
- * @param prevKeyPrefix The path to be converted.
- * @return The object path as "/volumeID/bucketID/ParentId/" or an empty string if an error occurs.
- * @throws IOException If database access fails.
- * @throws IllegalArgumentException If the provided path is invalid or cannot be converted.
- */
- public String convertToObjectPath(String prevKeyPrefix) throws IOException {
- try {
- String[] names = parseRequestPath(normalizePath(prevKeyPrefix, BucketLayout.FILE_SYSTEM_OPTIMIZED));
- Table openFileTable = omMetadataManager.getOpenKeyTable(BucketLayout.FILE_SYSTEM_OPTIMIZED);
-
- // Root-Level: Return the original path
- if (names.length == 0) {
- return prevKeyPrefix;
- }
-
- // Volume-Level: Fetch the volumeID
- String volumeName = names[0];
- validateNames(volumeName);
- String volumeKey = omMetadataManager.getVolumeKey(volumeName);
- long volumeId = omMetadataManager.getVolumeTable().getSkipCache(volumeKey).getObjectID();
- if (names.length == 1) {
- return constructObjectPathWithPrefix(volumeId);
- }
-
- // Bucket-Level: Fetch the bucketID
- String bucketName = names[1];
- validateNames(bucketName);
- String bucketKey = omMetadataManager.getBucketKey(volumeName, bucketName);
- OmBucketInfo bucketInfo = omMetadataManager.getBucketTable().getSkipCache(bucketKey);
- long bucketId = bucketInfo.getObjectID();
- if (names.length == 2 || bucketInfo.getBucketLayout() != BucketLayout.FILE_SYSTEM_OPTIMIZED) {
- return constructObjectPathWithPrefix(volumeId, bucketId);
- }
-
- // Directory or Key-Level: Check both key and directory
- BucketHandler handler =
- getBucketHandler(reconNamespaceSummaryManager, omMetadataManager, reconSCM, bucketInfo);
-
- if (names.length >= 3) {
- String lastEntiry = names[names.length - 1];
-
- // Check if the directory exists
- OmDirectoryInfo dirInfo = handler.getDirInfo(names);
- if (dirInfo != null && dirInfo.getName().equals(lastEntiry)) {
- return constructObjectPathWithPrefix(volumeId, bucketId, dirInfo.getObjectID()) + OM_KEY_PREFIX;
- }
-
- // Check if the key exists
- long dirID = handler.getDirObjectId(names, names.length);
- String keyKey = constructObjectPathWithPrefix(volumeId, bucketId, dirID) +
- OM_KEY_PREFIX + lastEntiry;
- OmKeyInfo keyInfo = openFileTable.getSkipCache(keyKey);
- if (keyInfo != null && keyInfo.getFileName().equals(lastEntiry)) {
- return constructObjectPathWithPrefix(volumeId, bucketId,
- keyInfo.getParentObjectID()) + OM_KEY_PREFIX + lastEntiry;
- }
-
- return prevKeyPrefix;
- }
- } catch (IllegalArgumentException e) {
- LOG.error(
- "IllegalArgumentException encountered while converting key prefix to object path: {}",
- prevKeyPrefix, e);
- throw e;
- } catch (RuntimeException e) {
- LOG.error(
- "RuntimeException encountered while converting key prefix to object path: {}",
- prevKeyPrefix, e);
- return prevKeyPrefix;
- }
- return prevKeyPrefix;
- }
-
- /**
- * Creates a KeyEntityInfo object from an OmKeyInfo object and the corresponding key.
- *
- * @param dbKey The key in the database corresponding to the OmKeyInfo object.
- * @param keyInfo The OmKeyInfo object to create the KeyEntityInfo from.
- * @return The KeyEntityInfo object created from the OmKeyInfo object and the key.
- */
- private KeyEntityInfo createKeyEntityInfoFromOmKeyInfo(String dbKey,
- OmKeyInfo keyInfo) {
- KeyEntityInfo keyEntityInfo = new KeyEntityInfo();
- keyEntityInfo.setKey(dbKey); // Set the DB key
- keyEntityInfo.setIsKey(keyInfo.isFile());
- keyEntityInfo.setPath(keyInfo.getKeyName()); // Assuming path is the same as key name
- keyEntityInfo.setInStateSince(keyInfo.getCreationTime());
- keyEntityInfo.setSize(keyInfo.getDataSize());
- keyEntityInfo.setReplicatedSize(keyInfo.getReplicatedSize());
- keyEntityInfo.setReplicationConfig(keyInfo.getReplicationConfig());
- return keyEntityInfo;
- }
-
-}
diff --git a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOmDBInsightEndPoint.java b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOmDBInsightEndPoint.java
index ed4b82fa3e04..61a9711876e7 100644
--- a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOmDBInsightEndPoint.java
+++ b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOmDBInsightEndPoint.java
@@ -90,6 +90,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -897,11 +898,11 @@ public void testGetOpenKeyInfo() throws Exception {
.get("/sampleVol/bucketOne/key_one");
assertEquals("key_one", omKeyInfo1.getKeyName());
Response openKeyInfoResp =
- omdbInsightEndpoint.getOpenKeyInfo(-1, "", true, true);
+ omdbInsightEndpoint.getOpenKeyInfo(-1, "", "", true, true);
KeyInsightInfoResponse keyInsightInfoResp =
(KeyInsightInfoResponse) openKeyInfoResp.getEntity();
assertNotNull(keyInsightInfoResp);
- assertEquals("key_one",
+ assertEquals("sampleVol/bucketOne/key_one",
keyInsightInfoResp.getNonFSOKeyInfoList().get(0).getPath());
}
@@ -1044,7 +1045,7 @@ public void testGetOpenKeyInfoLimitParam() throws Exception {
reconOMMetadataManager.getOpenKeyTable(getBucketLayout())
.put("/sampleVol/bucketOne/key_three", omKeyInfo3);
Response openKeyInfoResp =
- omdbInsightEndpoint.getOpenKeyInfo(2, "", true, true);
+ omdbInsightEndpoint.getOpenKeyInfo(2, "", "", true, true);
KeyInsightInfoResponse keyInsightInfoResp =
(KeyInsightInfoResponse) openKeyInfoResp.getEntity();
assertNotNull(keyInsightInfoResp);
@@ -1053,10 +1054,10 @@ public void testGetOpenKeyInfoLimitParam() throws Exception {
assertEquals(0, keyInsightInfoResp.getFsoKeyInfoList().size());
assertEquals(2, keyInsightInfoResp.getFsoKeyInfoList().size() +
keyInsightInfoResp.getNonFSOKeyInfoList().size());
- assertEquals("key_three",
+ assertEquals("sampleVol/bucketOne/key_three",
keyInsightInfoResp.getNonFSOKeyInfoList().get(1).getPath());
- openKeyInfoResp = omdbInsightEndpoint.getOpenKeyInfo(3, "", true, true);
+ openKeyInfoResp = omdbInsightEndpoint.getOpenKeyInfo(3, "", "", true, true);
keyInsightInfoResp =
(KeyInsightInfoResponse) openKeyInfoResp.getEntity();
assertNotNull(keyInsightInfoResp);
@@ -1065,7 +1066,7 @@ public void testGetOpenKeyInfoLimitParam() throws Exception {
assertEquals(1, keyInsightInfoResp.getFsoKeyInfoList().size());
assertEquals(3, keyInsightInfoResp.getFsoKeyInfoList().size() +
keyInsightInfoResp.getNonFSOKeyInfoList().size());
- assertEquals("key_three",
+ assertEquals("sampleVol/bucketOne/key_three",
keyInsightInfoResp.getNonFSOKeyInfoList().get(1).getPath());
}
@@ -1107,7 +1108,7 @@ public void testGetOpenKeyInfoWithIncludeFsoAndIncludeNonFsoParams()
// CASE 1 :- Display only FSO keys in response
// includeFsoKeys=true, includeNonFsoKeys=false
Response openKeyInfoResp =
- omdbInsightEndpoint.getOpenKeyInfo(10, "", true, false);
+ omdbInsightEndpoint.getOpenKeyInfo(10, "", "", true, false);
KeyInsightInfoResponse keyInsightInfoResp =
(KeyInsightInfoResponse) openKeyInfoResp.getEntity();
assertNotNull(keyInsightInfoResp);
@@ -1119,7 +1120,7 @@ public void testGetOpenKeyInfoWithIncludeFsoAndIncludeNonFsoParams()
// CASE 2 :- Display only Non-FSO keys in response
// includeFsoKeys=false, includeNonFsoKeys=true
openKeyInfoResp =
- omdbInsightEndpoint.getOpenKeyInfo(10, "", false, true);
+ omdbInsightEndpoint.getOpenKeyInfo(10, "", "", false, true);
keyInsightInfoResp = (KeyInsightInfoResponse) openKeyInfoResp.getEntity();
assertNotNull(keyInsightInfoResp);
assertEquals(0,
@@ -1130,7 +1131,7 @@ public void testGetOpenKeyInfoWithIncludeFsoAndIncludeNonFsoParams()
// CASE 3 :- Display both FSO and Non-FSO keys in response
// includeFsoKeys=true, includeNonFsoKeys=true
openKeyInfoResp =
- omdbInsightEndpoint.getOpenKeyInfo(10, "", true, true);
+ omdbInsightEndpoint.getOpenKeyInfo(10, "", "", true, true);
keyInsightInfoResp = (KeyInsightInfoResponse) openKeyInfoResp.getEntity();
assertNotNull(keyInsightInfoResp);
assertEquals(4,
@@ -1141,45 +1142,39 @@ public void testGetOpenKeyInfoWithIncludeFsoAndIncludeNonFsoParams()
// CASE 4 :- Don't Display both FSO and Non-FSO keys in response
// includeFsoKeys=false, includeNonFsoKeys=false
openKeyInfoResp =
- omdbInsightEndpoint.getOpenKeyInfo(10, "", false, false);
- keyInsightInfoResp = (KeyInsightInfoResponse) openKeyInfoResp.getEntity();
- assertNotNull(keyInsightInfoResp);
- assertEquals(0,
- keyInsightInfoResp.getFsoKeyInfoList().size());
- assertEquals(0,
- keyInsightInfoResp.getNonFSOKeyInfoList().size());
+ omdbInsightEndpoint.getOpenKeyInfo(10, "", "", false, false);
+ assertEquals(204, openKeyInfoResp.getStatus());
+ String entity = (String) openKeyInfoResp.getEntity();
+ assertTrue(entity.contains("No keys matched the search prefix"),
+ "Expected a message indicating no keys were found");
}
@Test
public void testGetOpenKeyInfoPrevKeyParam() throws Exception {
OmKeyInfo omKeyInfo1 =
- getOmKeyInfo("sampleVol", "bucketOne", "key_one", true);
+ getOmKeyInfo("sampleVol", "bucketOne", "key_1", true);
OmKeyInfo omKeyInfo2 =
- getOmKeyInfo("sampleVol", "bucketOne", "key_two", true);
+ getOmKeyInfo("sampleVol", "bucketOne", "key_2", true);
OmKeyInfo omKeyInfo3 =
- getOmKeyInfo("sampleVol", "bucketOne", "key_three", true);
+ getOmKeyInfo("sampleVol", "bucketOne", "key_3", true);
reconOMMetadataManager.getOpenKeyTable(getBucketLayout())
- .put("/sampleVol/bucketOne/key_one", omKeyInfo1);
+ .put("/sampleVol/bucketOne/key_1", omKeyInfo1);
reconOMMetadataManager.getOpenKeyTable(BucketLayout.FILE_SYSTEM_OPTIMIZED)
- .put("/sampleVol/bucketOne/key_two", omKeyInfo2);
+ .put("/sampleVol/bucketOne/key_2", omKeyInfo2);
reconOMMetadataManager.getOpenKeyTable(getBucketLayout())
- .put("/sampleVol/bucketOne/key_three", omKeyInfo3);
+ .put("/sampleVol/bucketOne/key_3", omKeyInfo3);
Response openKeyInfoResp =
- omdbInsightEndpoint.getOpenKeyInfo(-1, "/sampleVol/bucketOne/key_one",
+ omdbInsightEndpoint.getOpenKeyInfo(-1, "/sampleVol/bucketOne/key_1", "",
true, true);
KeyInsightInfoResponse keyInsightInfoResp =
(KeyInsightInfoResponse) openKeyInfoResp.getEntity();
assertNotNull(keyInsightInfoResp);
- assertEquals(1,
- keyInsightInfoResp.getNonFSOKeyInfoList().size());
+ assertEquals(1, keyInsightInfoResp.getNonFSOKeyInfoList().size());
assertEquals(1, keyInsightInfoResp.getFsoKeyInfoList().size());
- assertEquals(2, keyInsightInfoResp.getFsoKeyInfoList().size() +
- keyInsightInfoResp.getNonFSOKeyInfoList().size());
- assertEquals("key_three",
- keyInsightInfoResp.getNonFSOKeyInfoList().get(0).getPath());
- assertEquals("key_two",
- keyInsightInfoResp.getFsoKeyInfoList().get(0).getPath());
+ assertEquals(2, keyInsightInfoResp.getFsoKeyInfoList().size() + keyInsightInfoResp.getNonFSOKeyInfoList().size());
+ assertEquals("sampleVol/bucketOne/key_3", keyInsightInfoResp.getNonFSOKeyInfoList().get(0).getPath());
+ assertEquals("sampleVol/bucketOne/key_2", keyInsightInfoResp.getFsoKeyInfoList().get(0).getPath());
}
@Test
diff --git a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOMDBInsightSearchEndpoint.java b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOpenKeysSearchEndpoint.java
similarity index 83%
rename from hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOMDBInsightSearchEndpoint.java
rename to hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOpenKeysSearchEndpoint.java
index c3c2fe5debed..f55d988cfe01 100644
--- a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOMDBInsightSearchEndpoint.java
+++ b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestOpenKeysSearchEndpoint.java
@@ -81,12 +81,12 @@
* 11. Test Search Open Keys with Pagination: Verifies paginated search results.
* 12. Test Search in Empty Bucket: Checks the response for searching within an empty bucket.
*/
-public class TestOMDBInsightSearchEndpoint extends AbstractReconSqlDBTest {
+public class TestOpenKeysSearchEndpoint extends AbstractReconSqlDBTest {
@TempDir
private Path temporaryFolder;
private ReconOMMetadataManager reconOMMetadataManager;
- private OMDBInsightSearchEndpoint omdbInsightSearchEndpoint;
+ private OMDBInsightEndpoint omdbInsightEndpoint;
private OzoneConfiguration ozoneConfiguration;
private static final String ROOT_PATH = "/";
private static final String TEST_USER = "TestUser";
@@ -116,11 +116,8 @@ public void setUp() throws Exception {
.addBinding(OMDBInsightEndpoint.class)
.addBinding(ContainerHealthSchemaManager.class)
.build();
- reconNamespaceSummaryManager =
- reconTestInjector.getInstance(ReconNamespaceSummaryManager.class);
- omdbInsightSearchEndpoint = reconTestInjector.getInstance(
- OMDBInsightSearchEndpoint.class);
-
+ reconNamespaceSummaryManager = reconTestInjector.getInstance(ReconNamespaceSummaryManager.class);
+ omdbInsightEndpoint = reconTestInjector.getInstance(OMDBInsightEndpoint.class);
// populate OM DB and reprocess into Recon RocksDB
populateOMDB();
NSSummaryTaskWithFSO nSSummaryTaskWithFso =
@@ -150,26 +147,19 @@ private static OMMetadataManager initializeNewOmMetadataManager(
public void testRootLevelSearchRestriction() throws IOException {
// Test with root level path
String rootPath = "/";
- Response response = omdbInsightSearchEndpoint.searchOpenKeys(rootPath, 20, "");
+ Response response =
+ omdbInsightEndpoint.getOpenKeyInfo(-1, "", rootPath, true, true);
assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
String entity = (String) response.getEntity();
assertTrue(entity.contains("Invalid startPrefix: Path must be at the bucket level or deeper"),
"Expected a message indicating the path must be at the bucket level or deeper");
-
- // Test with root level path without trailing slash
- rootPath = "";
- response = omdbInsightSearchEndpoint.searchOpenKeys(rootPath, 20, "");
- assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- entity = (String) response.getEntity();
- assertTrue(entity.contains("Invalid startPrefix: Path must be at the bucket level or deeper"),
- "Expected a message indicating the path must be at the bucket level or deeper");
}
@Test
public void testVolumeLevelSearchRestriction() throws IOException {
// Test with volume level path
String volumePath = "/vola";
- Response response = omdbInsightSearchEndpoint.searchOpenKeys(volumePath, 20, "");
+ Response response = omdbInsightEndpoint.getOpenKeyInfo(20, "", volumePath, true, true);
assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
String entity = (String) response.getEntity();
assertTrue(entity.contains("Invalid startPrefix: Path must be at the bucket level or deeper"),
@@ -177,7 +167,7 @@ public void testVolumeLevelSearchRestriction() throws IOException {
// Test with another volume level path
volumePath = "/volb";
- response = omdbInsightSearchEndpoint.searchOpenKeys(volumePath, 20, "");
+ response = omdbInsightEndpoint.getOpenKeyInfo(20, "", volumePath, true, true);
assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
entity = (String) response.getEntity();
assertTrue(entity.contains("Invalid startPrefix: Path must be at the bucket level or deeper"),
@@ -188,7 +178,7 @@ public void testVolumeLevelSearchRestriction() throws IOException {
public void testBucketLevelSearch() throws IOException {
// Search inside FSO bucket
Response response =
- omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1", 20, "");
+ omdbInsightEndpoint.getOpenKeyInfo(20, "", "/vola/bucketa1", true, true);
assertEquals(200, response.getStatus());
KeyInsightInfoResponse result =
(KeyInsightInfoResponse) response.getEntity();
@@ -200,7 +190,7 @@ public void testBucketLevelSearch() throws IOException {
// Search inside OBS bucket
response =
- omdbInsightSearchEndpoint.searchOpenKeys("/volb/bucketb1", 20, "");
+ omdbInsightEndpoint.getOpenKeyInfo(20, "", "/volb/bucketb1", true, true);
assertEquals(200, response.getStatus());
result =
(KeyInsightInfoResponse) response.getEntity();
@@ -212,13 +202,13 @@ public void testBucketLevelSearch() throws IOException {
// Search Inside LEGACY bucket
response =
- omdbInsightSearchEndpoint.searchOpenKeys("/volc/bucketc1", 20, "");
+ omdbInsightEndpoint.getOpenKeyInfo(20, "", "/volc/bucketc1", true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(7, result.getNonFSOKeyInfoList().size());
// Test with bucket that does not exist
- response = omdbInsightSearchEndpoint.searchOpenKeys("/vola/nonexistentbucket", 20, "");
+ response = omdbInsightEndpoint.getOpenKeyInfo(20, "", "/vola/nonexistentbucket", true, true);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
String entity = (String) response.getEntity();
assertTrue(entity.contains("No keys matched the search prefix"),
@@ -228,7 +218,7 @@ public void testBucketLevelSearch() throws IOException {
@Test
public void testDirectoryLevelSearch() throws IOException {
Response response =
- omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/dira1", 20, "");
+ omdbInsightEndpoint.getOpenKeyInfo(20, "", "/vola/bucketa1/dira1", true, true);
assertEquals(200, response.getStatus());
KeyInsightInfoResponse result =
(KeyInsightInfoResponse) response.getEntity();
@@ -239,7 +229,7 @@ public void testDirectoryLevelSearch() throws IOException {
assertEquals(1000 * 3, result.getReplicatedDataSize());
response =
- omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/dira2", 20, "");
+ omdbInsightEndpoint.getOpenKeyInfo(20, "", "/vola/bucketa1/dira2", true, true);
assertEquals(200, response.getStatus());
result =
(KeyInsightInfoResponse) response.getEntity();
@@ -250,7 +240,7 @@ public void testDirectoryLevelSearch() throws IOException {
assertEquals(1000 * 3, result.getReplicatedDataSize());
response =
- omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/dira3", 20, "");
+ omdbInsightEndpoint.getOpenKeyInfo(20, "", "/vola/bucketa1/dira3", true, true);
assertEquals(200, response.getStatus());
result =
(KeyInsightInfoResponse) response.getEntity();
@@ -261,7 +251,7 @@ public void testDirectoryLevelSearch() throws IOException {
assertEquals(10000 * 3, result.getReplicatedDataSize());
// Test with non-existent directory
- response = omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/nonexistentdir", 20, "");
+ response = omdbInsightEndpoint.getOpenKeyInfo(20, "", "/vola/bucketa1/nonexistentdir", true, true);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
String entity = (String) response.getEntity();
assertTrue(entity.contains("No keys matched the search prefix"),
@@ -271,7 +261,7 @@ public void testDirectoryLevelSearch() throws IOException {
@Test
public void testKeyLevelSearch() throws IOException {
// FSO Bucket key-level search
- Response response = omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/filea1", 10, "");
+ Response response = omdbInsightEndpoint.getOpenKeyInfo(10, "", "/vola/bucketa1/filea1", true, true);
assertEquals(200, response.getStatus());
KeyInsightInfoResponse result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(1, result.getFsoKeyInfoList().size());
@@ -280,7 +270,7 @@ public void testKeyLevelSearch() throws IOException {
assertEquals(1000, result.getUnreplicatedDataSize());
assertEquals(1000 * 3, result.getReplicatedDataSize());
- response = omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/filea2", 10, "");
+ response = omdbInsightEndpoint.getOpenKeyInfo(10, "", "/vola/bucketa1/filea2", true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(1, result.getFsoKeyInfoList().size());
@@ -290,7 +280,8 @@ public void testKeyLevelSearch() throws IOException {
assertEquals(1000 * 3, result.getReplicatedDataSize());
// OBS Bucket key-level search
- response = omdbInsightSearchEndpoint.searchOpenKeys("/volb/bucketb1/fileb1", 10, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(10, "", "/volb/bucketb1/fileb1", true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(0, result.getFsoKeyInfoList().size());
@@ -299,7 +290,8 @@ public void testKeyLevelSearch() throws IOException {
assertEquals(1000, result.getUnreplicatedDataSize());
assertEquals(1000 * 3, result.getReplicatedDataSize());
- response = omdbInsightSearchEndpoint.searchOpenKeys("/volb/bucketb1/fileb2", 10, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(10, "", "/volb/bucketb1/fileb2", true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(0, result.getFsoKeyInfoList().size());
@@ -309,13 +301,15 @@ public void testKeyLevelSearch() throws IOException {
assertEquals(1000 * 3, result.getReplicatedDataSize());
// Test with non-existent key
- response = omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/nonexistentfile", 1, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(10, "", "/volb/bucketb1/nonexistentfile", true, true);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
String entity = (String) response.getEntity();
assertTrue(entity.contains("No keys matched the search prefix"),
"Expected a message indicating no keys were found");
- response = omdbInsightSearchEndpoint.searchOpenKeys("/volb/bucketb1/nonexistentfile", 1, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(10, "", "/volb/bucketb1/nonexistentfile", true, true);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
entity = (String) response.getEntity();
assertTrue(entity.contains("No keys matched the search prefix"),
@@ -326,29 +320,31 @@ public void testKeyLevelSearch() throws IOException {
@Test
public void testKeyLevelSearchUnderDirectory() throws IOException {
// FSO Bucket key-level search
- Response response =
- omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/dira1/innerfile", 10, "");
+ Response response = omdbInsightEndpoint
+ .getOpenKeyInfo(10, "", "/vola/bucketa1/dira1/innerfile", true, true);
assertEquals(200, response.getStatus());
KeyInsightInfoResponse result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(1, result.getFsoKeyInfoList().size());
assertEquals(0, result.getNonFSOKeyInfoList().size());
- response =
- omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/dira2/innerfile", 10, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(10, "", "/vola/bucketa1/dira2/innerfile", true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(1, result.getFsoKeyInfoList().size());
assertEquals(0, result.getNonFSOKeyInfoList().size());
// Test for unknown file in fso bucket
- response = omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/dira1/unknownfile", 10, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(10, "", "/vola/bucketa1/dira1/unknownfile", true, true);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
String entity = (String) response.getEntity();
assertTrue(entity.contains("No keys matched the search prefix"),
"Expected a message indicating no keys were found");
// Test for unknown file in fso bucket
- response = omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/dira2/unknownfile", 10, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(10, "", "/vola/bucketa1/dira2/unknownfile", true, true);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
entity = (String) response.getEntity();
assertTrue(entity.contains("No keys matched the search prefix"),
@@ -358,55 +354,55 @@ public void testKeyLevelSearchUnderDirectory() throws IOException {
@Test
public void testSearchUnderNestedDirectory() throws IOException {
- Response response = omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/dira3", 20,
- "");
+ Response response = omdbInsightEndpoint
+ .getOpenKeyInfo(20, "", "/vola/bucketa1/dira3", true, true);
assertEquals(200, response.getStatus());
KeyInsightInfoResponse result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(10, result.getFsoKeyInfoList().size());
assertEquals(0, result.getNonFSOKeyInfoList().size());
// Search under dira31
- response = omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1/dira3/dira31",
- 20, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(20, "", "/vola/bucketa1/dira3/dira31", true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(6, result.getFsoKeyInfoList().size());
assertEquals(0, result.getNonFSOKeyInfoList().size());
// Search under dira32
- response = omdbInsightSearchEndpoint.searchOpenKeys(
- "/vola/bucketa1/dira3/dira31/dira32", 20, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(20, "", "/vola/bucketa1/dira3/dira31/dira32", true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(3, result.getFsoKeyInfoList().size());
assertEquals(0, result.getNonFSOKeyInfoList().size());
// Search under dira33
- response = omdbInsightSearchEndpoint.searchOpenKeys(
- "/vola/bucketa1/dira3/dira31/dira32/dira33", 20, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(20, "", "/vola/bucketa1/dira3/dira31/dira32/dira33", true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(1, result.getFsoKeyInfoList().size());
assertEquals(0, result.getNonFSOKeyInfoList().size());
// Search for the exact file under dira33
- response = omdbInsightSearchEndpoint.searchOpenKeys(
- "/vola/bucketa1/dira3/dira31/dira32/dira33/file33_1", 20, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(20, "", "/vola/bucketa1/dira3/dira31/dira32/dira33/file33_1", true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(1, result.getFsoKeyInfoList().size());
assertEquals(0, result.getNonFSOKeyInfoList().size());
// Search for a non existant file under each nested directory
- response = omdbInsightSearchEndpoint.searchOpenKeys(
- "/vola/bucketa1/dira3/dira31/dira32/dira33/nonexistentfile", 20, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(20, "", "/vola/bucketa1/dira3/dira31/dira32/dira33/nonexistentfile", true, true);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
String entity = (String) response.getEntity();
assertTrue(entity.contains("No keys matched the search prefix"),
"Expected a message indicating no keys were found");
- response = omdbInsightSearchEndpoint.searchOpenKeys(
- "/vola/bucketa1/dira3/dira31/dira32/nonexistentfile", 20, "");
+ response = omdbInsightEndpoint
+ .getOpenKeyInfo(20, "", "/vola/bucketa1/dira3/dira31/dira32/nonexistentfile", true, true);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
entity = (String) response.getEntity();
assertTrue(entity.contains("No keys matched the search prefix"),
@@ -416,7 +412,7 @@ public void testSearchUnderNestedDirectory() throws IOException {
@Test
public void testLimitSearch() throws IOException {
Response response =
- omdbInsightSearchEndpoint.searchOpenKeys("/vola/bucketa1", 2, "");
+ omdbInsightEndpoint.getOpenKeyInfo(2, "", "/vola/bucketa1", true, true);
assertEquals(200, response.getStatus());
KeyInsightInfoResponse result =
(KeyInsightInfoResponse) response.getEntity();
@@ -428,8 +424,8 @@ public void testLimitSearch() throws IOException {
public void testSearchOpenKeysWithBadRequest() throws IOException {
// Give a negative limit
int negativeLimit = -1;
- Response response = omdbInsightSearchEndpoint.searchOpenKeys("@323232", negativeLimit, "");
-
+ Response response = omdbInsightEndpoint
+ .getOpenKeyInfo(negativeLimit, "", "@323232", true, true);
// Then the response should indicate that the request was bad
assertEquals(Response.Status.BAD_REQUEST.getStatusCode(),
response.getStatus(), "Expected a 400 BAD REQUEST status");
@@ -438,7 +434,7 @@ public void testSearchOpenKeysWithBadRequest() throws IOException {
assertTrue(entity.contains("Invalid startPrefix: Path must be at the bucket level or deeper"),
"Expected a message indicating the path must be at the bucket level or deeper");
- response = omdbInsightSearchEndpoint.searchOpenKeys("///", 20, "");
+ response = omdbInsightEndpoint.getOpenKeyInfo(20, "", "///", true, true);
assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
entity = (String) response.getEntity();
assertTrue(entity.contains("Invalid startPrefix: Path must be at the bucket level or deeper"),
@@ -447,8 +443,8 @@ public void testSearchOpenKeysWithBadRequest() throws IOException {
@Test
public void testLastKeyInResponse() throws IOException {
- Response response =
- omdbInsightSearchEndpoint.searchOpenKeys("/volb/bucketb1", 20, "");
+ Response response = omdbInsightEndpoint
+ .getOpenKeyInfo(20, "", "/volb/bucketb1", true, true);
assertEquals(200, response.getStatus());
KeyInsightInfoResponse result =
(KeyInsightInfoResponse) response.getEntity();
@@ -470,7 +466,7 @@ public void testSearchOpenKeysWithPagination() throws IOException {
String prevKey = "";
// Perform the first search request
- Response response = omdbInsightSearchEndpoint.searchOpenKeys(startPrefix, limit, prevKey);
+ Response response = omdbInsightEndpoint.getOpenKeyInfo(limit, prevKey, startPrefix, true, true);
assertEquals(200, response.getStatus());
KeyInsightInfoResponse result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(2, result.getNonFSOKeyInfoList().size());
@@ -481,7 +477,7 @@ public void testSearchOpenKeysWithPagination() throws IOException {
assertNotNull(prevKey, "Last key should not be null");
// Perform the second search request using the last key
- response = omdbInsightSearchEndpoint.searchOpenKeys(startPrefix, limit, prevKey);
+ response = omdbInsightEndpoint.getOpenKeyInfo(limit, prevKey, startPrefix, true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(2, result.getNonFSOKeyInfoList().size());
@@ -492,7 +488,7 @@ public void testSearchOpenKeysWithPagination() throws IOException {
assertNotNull(prevKey, "Last key should not be null");
// Perform the third search request using the last key
- response = omdbInsightSearchEndpoint.searchOpenKeys(startPrefix, limit, prevKey);
+ response = omdbInsightEndpoint.getOpenKeyInfo(limit, prevKey, startPrefix, true, true);
assertEquals(200, response.getStatus());
result = (KeyInsightInfoResponse) response.getEntity();
assertEquals(1, result.getNonFSOKeyInfoList().size());
@@ -504,13 +500,61 @@ public void testSearchOpenKeysWithPagination() throws IOException {
@Test
public void testSearchInEmptyBucket() throws IOException {
// Search in empty bucket bucketb2
- Response response = omdbInsightSearchEndpoint.searchOpenKeys("/volb/bucketb2", 20, "");
+ Response response = omdbInsightEndpoint.getOpenKeyInfo(20, "", "/volb/bucketb2", true, true);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
String entity = (String) response.getEntity();
assertTrue(entity.contains("No keys matched the search prefix"),
"Expected a message indicating no keys were found");
}
+ @Test
+ public void testSearchWithPrevKeyOnly() throws IOException {
+ String prevKey = "/volb/bucketb1/fileb1"; // Key exists in volb/bucketb1
+ Response response = omdbInsightEndpoint.getOpenKeyInfo(4, prevKey, "", true, true);
+
+ assertEquals(200, response.getStatus());
+
+ KeyInsightInfoResponse result = (KeyInsightInfoResponse) response.getEntity();
+ assertEquals(4, result.getNonFSOKeyInfoList().size(), "Expected 4 remaining keys after 'fileb1'");
+ assertEquals("/volb/bucketb1/fileb5", result.getLastKey(), "Expected last key to be 'fileb5'");
+ }
+
+ @Test
+ public void testSearchWithEmptyPrevKeyAndStartPrefix() throws IOException {
+ Response response = omdbInsightEndpoint.getOpenKeyInfo(-1, "", "", true, true);
+
+ assertEquals(200, response.getStatus());
+
+ KeyInsightInfoResponse result = (KeyInsightInfoResponse) response.getEntity();
+ // Assert all the keys are returned
+ assertEquals(12, result.getNonFSOKeyInfoList().size(), "Expected all keys to be returned");
+ }
+
+ @Test
+ public void testSearchWithStartPrefixOnly() throws IOException {
+ String startPrefix = "/volb/bucketb1/";
+ Response response = omdbInsightEndpoint.getOpenKeyInfo(10, "", startPrefix, true, true);
+
+ assertEquals(200, response.getStatus());
+
+ KeyInsightInfoResponse result = (KeyInsightInfoResponse) response.getEntity();
+ assertEquals(5, result.getNonFSOKeyInfoList().size(), "Expected 5 keys starting with 'fileb1'");
+ assertEquals("/volb/bucketb1/fileb5", result.getLastKey(), "Expected last key to be 'fileb5'");
+ }
+
+ @Test
+ public void testSearchWithPrevKeyAndStartPrefix() throws IOException {
+ String startPrefix = "/volb/bucketb1/";
+ String prevKey = "/volb/bucketb1/fileb1";
+ Response response = omdbInsightEndpoint.getOpenKeyInfo(10, prevKey, startPrefix, true, true);
+
+ assertEquals(200, response.getStatus());
+
+ KeyInsightInfoResponse result = (KeyInsightInfoResponse) response.getEntity();
+ assertEquals(4, result.getNonFSOKeyInfoList().size(), "Expected 4 keys after 'fileb1'");
+ assertEquals("/volb/bucketb1/fileb5", result.getLastKey(), "Expected last key to be 'fileb5'");
+ }
+
/**
* Tests the NSSummaryEndpoint for a given volume, bucket, and directory structure.
* The test setup mimics the following filesystem structure with specified sizes:
@@ -566,7 +610,7 @@ private void populateOMDB() throws Exception {
// Create Bucket in volb
createBucket("volb", "bucketb1", 1000 + 1000 + 1000 + 1000 + 1000,
- getOBSBucketLayout());
+ getOBSBucketLayout());
createBucket("volb", "bucketb2", 0, getOBSBucketLayout()); // Empty Bucket
// Create Bucket in volc