diff --git a/src/main/java/com/epam/aidial/core/controller/ResourceController.java b/src/main/java/com/epam/aidial/core/controller/ResourceController.java index b49ee99dd..347fcaf3c 100644 --- a/src/main/java/com/epam/aidial/core/controller/ResourceController.java +++ b/src/main/java/com/epam/aidial/core/controller/ResourceController.java @@ -50,18 +50,20 @@ protected Future handle(ResourceDescription descriptor) { private Future getMetadata(ResourceDescription descriptor) { String token; int limit; + boolean recursive; try { token = context.getRequest().getParam("token"); limit = Integer.parseInt(context.getRequest().getParam("limit", "100")); + recursive = Boolean.parseBoolean(context.getRequest().getParam("recursive", "false")); if (limit < 0 || limit > 1000) { throw new IllegalArgumentException("Limit is out of allowed range"); } } catch (Throwable error) { - return context.respond(HttpStatus.BAD_REQUEST, "Bad query parameters. Limit must be in [0, 1000] range"); + return context.respond(HttpStatus.BAD_REQUEST, "Bad query parameters. Limit must be in [0, 1000] range. Recursive must be true/false"); } - return vertx.executeBlocking(() -> service.getMetadata(descriptor, token, limit)) + return vertx.executeBlocking(() -> service.getMetadata(descriptor, token, limit, recursive)) .onSuccess(result -> { if (result == null) { context.respond(HttpStatus.NOT_FOUND, "Not found: " + descriptor.getUrl()); diff --git a/src/main/java/com/epam/aidial/core/service/ResourceService.java b/src/main/java/com/epam/aidial/core/service/ResourceService.java index 6361112c3..9e65596cb 100644 --- a/src/main/java/com/epam/aidial/core/service/ResourceService.java +++ b/src/main/java/com/epam/aidial/core/service/ResourceService.java @@ -104,15 +104,15 @@ public void close() { } @Nullable - public MetadataBase getMetadata(ResourceDescription descriptor, String token, int limit) { + public MetadataBase getMetadata(ResourceDescription descriptor, String token, int limit, boolean recursive) { return descriptor.isFolder() - ? getFolderMetadata(descriptor, token, limit) + ? getFolderMetadata(descriptor, token, limit, recursive) : getItemMetadata(descriptor); } - private ResourceFolderMetadata getFolderMetadata(ResourceDescription descriptor, String token, int limit) { + private ResourceFolderMetadata getFolderMetadata(ResourceDescription descriptor, String token, int limit, boolean recursive) { String blobKey = blobKey(descriptor); - PageSet set = blobStore.list(blobKey, token, limit); + PageSet set = blobStore.list(blobKey, token, limit, recursive); if (set.isEmpty() && !descriptor.isRootFolder()) { return null; diff --git a/src/main/java/com/epam/aidial/core/storage/BlobStorage.java b/src/main/java/com/epam/aidial/core/storage/BlobStorage.java index c938fe718..a57a461d1 100644 --- a/src/main/java/com/epam/aidial/core/storage/BlobStorage.java +++ b/src/main/java/com/epam/aidial/core/storage/BlobStorage.java @@ -189,11 +189,16 @@ public MetadataBase listMetadata(ResourceDescription resource) { } } - public PageSet list(String absoluteFilePath, String afterMarker, int maxResults) { + public PageSet list(String absoluteFilePath, String afterMarker, int maxResults, boolean recursive) { ListContainerOptions options = new ListContainerOptions() .prefix(absoluteFilePath) - .maxResults(maxResults) - .delimiter(BlobStorageUtil.PATH_SEPARATOR); + .maxResults(maxResults); + + if (recursive) { + options.recursive(); + } else { + options.delimiter(BlobStorageUtil.PATH_SEPARATOR); + } if (afterMarker != null) { options.afterMarker(afterMarker); diff --git a/src/test/java/com/epam/aidial/core/ResourceApiTest.java b/src/test/java/com/epam/aidial/core/ResourceApiTest.java index 00ee31406..5fcc7723f 100644 --- a/src/test/java/com/epam/aidial/core/ResourceApiTest.java +++ b/src/test/java/com/epam/aidial/core/ResourceApiTest.java @@ -131,6 +131,9 @@ void testWorkflow() { response = request(HttpMethod.PUT, "/folder/conversation", "12345"); verifyNotExact(response, 200, "\"url\":\"conversations/3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST/folder/conversation\""); + response = metadata("/?recursive=true"); + verifyNotExact(response, 200, "\"url\":\"conversations/3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST/folder/conversation\""); + response = request(HttpMethod.PUT, "/folder/conversation", "12345", "if-none-match", "*"); verifyNotExact(response, 409, "Resource already exists: conversations/3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST/folder/conversation");