Skip to content

Commit

Permalink
feat: implement a method to delete a directory from a template.
Browse files Browse the repository at this point in the history
This change allows developers to directly delete a directory and all its containing files and directories from a given service template.

As an additional functionality, this method is also exposed to the HTTP Rest API much like the file deletion method already is.
  • Loading branch information
GiantTreeLP committed Apr 30, 2023
1 parent 785e4a6 commit 56b9a3f
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,17 @@ default boolean deployDirectory(@NonNull ServiceTemplate target, @NonNull Path d
*/
boolean deleteFile(@NonNull ServiceTemplate template, @NonNull String path);

/**
* Deletes the given directory at the given path in the given template in this storage.
* This method recursively deletes all files and directories inside the given directory.
*
* @param template the template in which the directory to delete is located in.
* @param path the path to the directory in the template to delete.
* @return true if the directory at the given path was deleted successfully, false otherwise.
* @throws NullPointerException if the given template or path is null.
*/
boolean deleteDirectory(@NonNull ServiceTemplate template, @NonNull String path);

/**
* Opens a new input stream to read the content of the file at the given path in the given template in this storage.
* This method returns null if either the file doesn't exist or is a directory.
Expand Down Expand Up @@ -480,6 +491,19 @@ default boolean deployDirectory(@NonNull ServiceTemplate target, @NonNull Path d
return Task.supply(() -> this.deleteFile(template, path));
}

/**
* Deletes the given directory at the given path in the given template in this storage. This method recursively
* deletes all files and directories inside the given directory.
*
* @param template the template in which the directory to delete is located in.
* @param path the path to the directory in the template to delete.
* @return a task completed with true if the directory at the given path was deleted successfully, false otherwise.
* @throws NullPointerException if the given template or path is null.
*/
default @NonNull Task<Boolean> deleteDirectoryAsync(@NonNull ServiceTemplate template, @NonNull String path) {
return Task.supply(() -> this.deleteDirectory(template, path));
}

/**
* Opens a new input stream to read the content of the file at the given path in the given template in this storage.
* This method returns null if either the file doesn't exist or is a directory.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,25 @@ private void handleFileDeleteRequest(
});
}

@BearerAuth
@HttpRequestHandler(paths = "/api/v2/template/{storage}/{prefix}/{name}/directory", methods = "DELETE")
private void handleDirectoryDeleteRequest(
@NonNull HttpContext context,
@NonNull @RequestPathParam("storage") String storageName,
@NonNull @RequestPathParam("prefix") String prefix,
@NonNull @RequestPathParam("name") String templateName,
@NonNull @FirstRequestQueryParam("path") String path
) {
this.handleWithTemplateContext(context, storageName, prefix, templateName, (template, storage) -> {
var status = storage.deleteDirectory(template, path);
this.ok(context)
.body(status ? this.success().toString() : this.failure().toString())
.context()
.closeAfter(true)
.cancelNext(true);
});
}

@BearerAuth
@HttpRequestHandler(paths = "/api/v2/template/{storage}/{prefix}/{name}", methods = "DELETE")
private void handleTemplateDeleteRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,29 @@ public boolean deleteFile(@NonNull ServiceTemplate template, @NonNull String pat
}
}

@Override
public boolean deleteDirectory(@NonNull ServiceTemplate template, @NonNull String path) {
try {
// get the contents we want to delete
Set<ObjectIdentifier> toDelete = new HashSet<>();
this.listAllObjects(
this.getBucketPath(template, path),
null,
object -> toDelete.add(ObjectIdentifier.builder().key(object.key()).build()));

// build the delete request
var deleteRequest = DeleteObjectsRequest.builder()
.bucket(this.config().bucket())
.delete(Delete.builder().quiet(true).objects(toDelete).build())
.build();
this.client.deleteObjects(deleteRequest);
// success
return true;
} catch (Exception exception) {
return false;
}
}

@Override
public @Nullable InputStream newInputStream(@NonNull ServiceTemplate template, @NonNull String path) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,15 @@ public boolean deleteFile(@NonNull ServiceTemplate template, @NonNull String pat
}, false);
}

@Override
public boolean deleteDirectory(@NonNull ServiceTemplate template, @NonNull String path) {
return this.executeWithClient(client -> {
this.deleteDir(client, this.constructRemotePath(template, path));
client.rmdir(this.constructRemotePath(template, path));
return true;
}, false);
}

@Override
public @Nullable InputStream newInputStream(@NonNull ServiceTemplate st, @NonNull String path) throws IOException {
var client = this.pool.takeClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,17 @@ public boolean deleteFile(@NonNull ServiceTemplate template, @NonNull String pat
return false;
}

@Override
public boolean deleteDirectory(@NonNull ServiceTemplate template, @NonNull String path) {
var dirPath = this.getTemplatePath(template).resolve(path);
if (Files.exists(dirPath) && Files.isDirectory(dirPath)) {
FileUtil.delete(dirPath);
return true;
}

return false;
}

@Override
public @Nullable InputStream newInputStream(
@NonNull ServiceTemplate template,
Expand Down

0 comments on commit 56b9a3f

Please sign in to comment.