Skip to content

Commit

Permalink
bug(CLI) fix files pull with limited perms Refs: #27386 (#27897)
Browse files Browse the repository at this point in the history
* #27386 fix files pull with limited perms

* #27386 adjusting test
  • Loading branch information
fabrizzio-dotCMS committed Mar 11, 2024
1 parent ad4f2df commit d9a8c5c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 23 deletions.
Expand Up @@ -191,10 +191,8 @@ private CompletableFuture<TraverseTaskResult> processSubFolders(
task::compute, executor
).thenCompose(Function.identity());
futures.add(future);
} catch (TraversalTaskException e) {
throw e;
} catch (Exception e) {
throw new TraversalTaskException(e.getMessage(), e);
handleException(errors, e);
}
} else {

Expand Down Expand Up @@ -335,4 +333,24 @@ private FolderView retrieveFolderInformation(final String siteName, final String
}
}

/**
* Handles an exception that occurred during the execution of a traversal task.
*
* @param errors The list of exceptions to which the error should be added.
* @param e The exception that occurred.
*/
private void handleException(List<Exception> errors, Exception e) {

if (traversalTaskParams.failFast()) {

if (e instanceof TraversalTaskException) {
throw (TraversalTaskException) e;
}

throw new TraversalTaskException(e.getMessage(), e);
} else {
errors.add(e);
}
}

}
Expand Up @@ -97,19 +97,17 @@ public int pull(List<FileTraverseResult> contents,
PullOptions pullOptions,
OutputOptionMixin output) throws ExecutionException, InterruptedException {

//Now we're going to partition the list of results into two lists:
//The first one will contain the results that have exceptions and the second one will contain the results that don't have exceptions
final Map<Boolean, List<FileTraverseResult>> partitioned = contents.stream()
.collect(Collectors.partitioningBy(pojo -> !pojo.exceptions().isEmpty()));

//Inform the user about any errors that could have occurred during the traversal process
final List<FileTraverseResult> failed = partitioned.get(true);
//Collect all exceptions from the returned contents
final List<Exception> allExceptions = contents.stream().map(FileTraverseResult::exceptions)
.flatMap(List::stream).collect(Collectors.toList());

//Any failed TreeNode will not be present
//So no need to separate the results

//Save the error code for the traversal process. This will be used to determine the exit code of the command if greater than 0 (zero)
int errorCode = handleExceptions(failed.stream().map(FileTraverseResult::exceptions).flatMap(List::stream).collect(Collectors.toList()), output);
int errorCode = handleExceptions(allExceptions, output);

//The second list will contain the results that don't have exceptions
//We assume that the traversal process was successful for these results
final List<FileTraverseResult> success = partitioned.get(false);

boolean preserve = false;
boolean includeEmptyFolders = false;
Expand All @@ -121,9 +119,9 @@ public int pull(List<FileTraverseResult> contents,
getOrDefault(INCLUDE_EMPTY_FOLDERS, false);
}

output.info(startPullingHeader(success));
output.info(startPullingHeader(contents));

for (final var content : success) {
for (final var content : contents) {

var errors = pullTree(
content,
Expand Down
Expand Up @@ -836,6 +836,17 @@ void Test_Handle_Early_Thrown_Exception_Expect_SOFTWARE_ExitCode() throws IOExce
final var testSiteName = String.format("non-existent-site-%s", UUID.randomUUID());
final var folderPath = String.format("//%s", testSiteName);
OutputOptionMixin outputOptions = new MockOutputOptionMixin();
FileFetcher mockedProvider = Mockito.mock(FileFetcher.class);
//But here is where the real test lies. We are going to return a List of FileTraverseResult with multiple exceptions
//They all should be logged and the first one should be the one that triggers the exit code
when(mockedProvider.fetchByKey(anyString(), anyBoolean(),any())).thenReturn(
FileTraverseResult.builder().tree(new TreeNode(FolderView.builder().host(testSiteName).path("/test").name("name").build())).exceptions(
List.of(
new UnauthorizedException(),
new TraversalTaskException("Unexpected Error Traversing folders ")
)).build()
);

var tempFolder = filesTestHelper.createTempFolder();
var workspace = workspaceManager.getOrCreate(tempFolder);
try {
Expand All @@ -849,7 +860,7 @@ void Test_Handle_Early_Thrown_Exception_Expect_SOFTWARE_ExitCode() throws IOExce
maxRetryAttempts(0).
build(),
outputOptions,
fileProvider,
mockedProvider,
filePullHandler
);
} catch (Exception e) {
Expand Down Expand Up @@ -879,17 +890,15 @@ void Test_Handle_Multiple_Thrown_Exceptions() throws IOException {

MockOutputOptionMixin outputOptions = new MockOutputOptionMixin();
FileFetcher mockedProvider = Mockito.mock(FileFetcher.class);


//But here is where the real test lies. We are going to return a List of FileTraverseResult with multiple exceptions
//They all should be logged and the first one should be the one that triggers the exit code
when(mockedProvider.fetch(anyBoolean(), any())).thenReturn(
List.of(
FileTraverseResult.builder().tree(Optional.empty()).exceptions(List.of(new UnauthorizedException())).build(),
FileTraverseResult.builder().tree(Optional.empty()).exceptions(List.of(new TraversalTaskException("Unexpected Error Traversing folders "))).build(),
FileTraverseResult.builder().tree(
new TreeNode(FolderView.builder().host(testSiteName).path("/test").name("name").build())
).exceptions(List.of()).build()
FileTraverseResult.builder().tree(new TreeNode(FolderView.builder().host(testSiteName).path("/test").name("name").build())).exceptions(
List.of(
new UnauthorizedException(),
new TraversalTaskException("Unexpected Error Traversing folders ")
)).build()
));

//We're going to use PullHandler but this time we do not specify the contentKey so the fetch method gets called
Expand Down

0 comments on commit d9a8c5c

Please sign in to comment.