|
19 | 19 |
|
20 | 20 | import org.apache.hadoop.hdds.scm.server.OzoneStorageContainerManager; |
21 | 21 | import org.apache.hadoop.ozone.OmUtils; |
| 22 | +import org.apache.hadoop.ozone.om.helpers.BucketLayout; |
22 | 23 | import org.apache.hadoop.ozone.recon.ReconConstants; |
23 | 24 | import org.apache.hadoop.ozone.recon.api.types.NamespaceSummaryResponse; |
24 | 25 | import org.apache.hadoop.ozone.recon.api.types.DUResponse; |
@@ -60,9 +61,18 @@ public EntityHandler( |
60 | 61 | this.omMetadataManager = omMetadataManager; |
61 | 62 | this.reconSCM = reconSCM; |
62 | 63 | this.bucketHandler = bucketHandler; |
63 | | - normalizedPath = normalizePath(path); |
64 | | - names = parseRequestPath(normalizedPath); |
65 | 64 |
|
| 65 | + // Defaulting to FILE_SYSTEM_OPTIMIZED if bucketHandler is null |
| 66 | + BucketLayout layout = |
| 67 | + (bucketHandler != null) ? bucketHandler.getBucketLayout() : |
| 68 | + BucketLayout.FILE_SYSTEM_OPTIMIZED; |
| 69 | + |
| 70 | + // Normalize the path based on the determined layout |
| 71 | + normalizedPath = normalizePath(path, layout); |
| 72 | + |
| 73 | + // Choose the parsing method based on the bucket layout |
| 74 | + names = (layout == BucketLayout.OBJECT_STORE) ? |
| 75 | + parseObjectStorePath(normalizedPath) : parseRequestPath(normalizedPath); |
66 | 76 | } |
67 | 77 |
|
68 | 78 | public abstract NamespaceSummaryResponse getSummaryResponse() |
@@ -118,7 +128,8 @@ public static EntityHandler getEntityHandler( |
118 | 128 | String path) throws IOException { |
119 | 129 | BucketHandler bucketHandler; |
120 | 130 |
|
121 | | - String normalizedPath = normalizePath(path); |
| 131 | + String normalizedPath = |
| 132 | + normalizePath(path, BucketLayout.FILE_SYSTEM_OPTIMIZED); |
122 | 133 | String[] names = parseRequestPath(normalizedPath); |
123 | 134 | if (path.equals(OM_KEY_PREFIX)) { |
124 | 135 | return EntityType.ROOT.create(reconNamespaceSummaryManager, |
@@ -156,23 +167,36 @@ public static EntityHandler getEntityHandler( |
156 | 167 | String volName = names[0]; |
157 | 168 | String bucketName = names[1]; |
158 | 169 |
|
159 | | - String keyName = BucketHandler.getKeyName(names); |
160 | | - |
| 170 | + // Assuming getBucketHandler already validates volume and bucket existence |
161 | 171 | bucketHandler = BucketHandler.getBucketHandler( |
162 | | - reconNamespaceSummaryManager, |
163 | | - omMetadataManager, reconSCM, |
164 | | - volName, bucketName); |
| 172 | + reconNamespaceSummaryManager, omMetadataManager, reconSCM, volName, |
| 173 | + bucketName); |
165 | 174 |
|
166 | | - // check if either volume or bucket doesn't exist |
167 | | - if (bucketHandler == null |
168 | | - || !omMetadataManager.volumeExists(volName) |
169 | | - || !bucketHandler.bucketExists(volName, bucketName)) { |
| 175 | + if (bucketHandler == null) { |
170 | 176 | return EntityType.UNKNOWN.create(reconNamespaceSummaryManager, |
171 | | - omMetadataManager, reconSCM, null, path); |
| 177 | + omMetadataManager, reconSCM, null, path); |
| 178 | + } |
| 179 | + |
| 180 | + // Directly handle path normalization and parsing based on the layout |
| 181 | + if (bucketHandler.getBucketLayout() == BucketLayout.OBJECT_STORE) { |
| 182 | + String[] parsedObjectLayoutPath = parseObjectStorePath( |
| 183 | + normalizePath(path, bucketHandler.getBucketLayout())); |
| 184 | + if (parsedObjectLayoutPath == null) { |
| 185 | + return EntityType.UNKNOWN.create(reconNamespaceSummaryManager, |
| 186 | + omMetadataManager, reconSCM, null, path); |
| 187 | + } |
| 188 | + // Use the key part directly from the parsed path |
| 189 | + return bucketHandler.determineKeyPath(parsedObjectLayoutPath[2]) |
| 190 | + .create(reconNamespaceSummaryManager, omMetadataManager, reconSCM, |
| 191 | + bucketHandler, path); |
| 192 | + } else { |
| 193 | + // Use the existing names array for non-OBJECT_STORE layouts to derive |
| 194 | + // the keyName |
| 195 | + String keyName = BucketHandler.getKeyName(names); |
| 196 | + return bucketHandler.determineKeyPath(keyName) |
| 197 | + .create(reconNamespaceSummaryManager, omMetadataManager, reconSCM, |
| 198 | + bucketHandler, path); |
172 | 199 | } |
173 | | - return bucketHandler.determineKeyPath(keyName) |
174 | | - .create(reconNamespaceSummaryManager, |
175 | | - omMetadataManager, reconSCM, bucketHandler, path); |
176 | 200 | } |
177 | 201 | } |
178 | 202 |
|
@@ -256,7 +280,52 @@ public static String[] parseRequestPath(String path) { |
256 | 280 | return names; |
257 | 281 | } |
258 | 282 |
|
259 | | - private static String normalizePath(String path) { |
| 283 | + /** |
| 284 | + * Splits an object store path into volume, bucket, and key name components. |
| 285 | + * |
| 286 | + * This method parses a path of the format "/volumeName/bucketName/keyName", |
| 287 | + * including paths with additional '/' characters within the key name. It's |
| 288 | + * designed for object store paths where the first three '/' characters |
| 289 | + * separate the root, volume and bucket names from the key name. |
| 290 | + * |
| 291 | + * @param path The object store path to parse, starting with a slash. |
| 292 | + * @return A String array with three elements: volume name, bucket name, and |
| 293 | + * key name, or {null} if the path format is invalid. |
| 294 | + */ |
| 295 | + public static String[] parseObjectStorePath(String path) { |
| 296 | + // Removing the leading slash for correct splitting |
| 297 | + path = path.substring(1); |
| 298 | + |
| 299 | + // Splitting the modified path by "/", limiting to 3 parts |
| 300 | + String[] parts = path.split("/", 3); |
| 301 | + |
| 302 | + // Checking if we correctly obtained 3 parts after removing the leading slash |
| 303 | + if (parts.length <= 3) { |
| 304 | + return parts; |
| 305 | + } else { |
| 306 | + return null; |
| 307 | + } |
| 308 | + } |
| 309 | + |
| 310 | + /** |
| 311 | + * Normalizes a given path based on the specified bucket layout. |
| 312 | + * |
| 313 | + * This method adjusts the path according to the bucket layout. |
| 314 | + * For {OBJECT_STORE Layout}, it normalizes the path up to the bucket level |
| 315 | + * using OmUtils.normalizePathUptoBucket. For other layouts, it |
| 316 | + * normalizes the entire path, including the key, using |
| 317 | + * OmUtils.normalizeKey, and does not preserve any trailing slashes. |
| 318 | + * The normalized path will always be prefixed with OM_KEY_PREFIX to ensure it |
| 319 | + * is consistent with the expected format for object storage paths in Ozone. |
| 320 | + * |
| 321 | + * @param path |
| 322 | + * @param bucketLayout |
| 323 | + * @return A normalized path |
| 324 | + */ |
| 325 | + private static String normalizePath(String path, BucketLayout bucketLayout) { |
| 326 | + if (bucketLayout == BucketLayout.OBJECT_STORE) { |
| 327 | + return OM_KEY_PREFIX + OmUtils.normalizePathUptoBucket(path); |
| 328 | + } |
260 | 329 | return OM_KEY_PREFIX + OmUtils.normalizeKey(path, false); |
261 | 330 | } |
262 | 331 | } |
0 commit comments