Skip to content

Commit a0e4fb0

Browse files
authored
Merge pull request #123 from pwssOrg/114-implement-parallel-retrieval-of-monitored-directories-using-futures
114 implement parallel retrieval of monitored directories using futures
2 parents afa1b55 + 737619c commit a0e4fb0

9 files changed

Lines changed: 237 additions & 244 deletions

File tree

File-Integrity-Scanner/src/main/java/org/pwss/file_integrity_scanner/component/DirectoryTraverser.java

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
import org.pwss.io_file.FileTraverserImpl;
44
import org.pwss.util.PWSSDirectoryNavUtil;
5+
import org.springframework.scheduling.annotation.Async;
56
import org.springframework.stereotype.Component;
67

78
import java.io.File;
89
import java.util.List;
910
import java.util.Optional;
11+
import java.util.concurrent.CompletableFuture;
1012
import java.util.concurrent.ExecutionException;
1113
import java.util.concurrent.Future;
1214

@@ -17,45 +19,43 @@
1719
@Component
1820
public class DirectoryTraverser {
1921

22+
private final org.slf4j.Logger log;
23+
24+
public DirectoryTraverser() {
25+
this.log = org.slf4j.LoggerFactory.getLogger(DirectoryTraverser.class);
26+
}
27+
2028
/**
21-
* Scans a directory and retrieves a list of all files within it.
29+
* Collects all files in a directory asynchronously.
30+
* <p>
31+
* This method uses a `FileTraverserImpl` instance to traverse the specified directory
32+
* and retrieve a list of files. The traversal is performed asynchronously, and the
33+
* result is returned as a `Future`.
2234
*
2335
* @param directoryPath the path of the directory to scan
24-
* @return a list of files found in the directory
25-
* @throws ExecutionException if an error occurs during the asynchronous file
26-
* traversal
27-
* @throws InterruptedException if the thread executing the file traversal is
28-
* interrupted
36+
* @return a Future containing the list of files found in the directory
2937
*/
30-
public final List<File> collectFilesInDirectory(String directoryPath)
31-
throws ExecutionException, InterruptedException {
38+
@Async
39+
public Future<List<File>> collectFilesInDirectory(String directoryPath) {
40+
log.info("Starting asynchronous traversal scan for directory: {}", directoryPath);
3241
FileTraverserImpl traverser = new FileTraverserImpl();
33-
Future<List<File>> future = traverser.traverse(directoryPath);
34-
35-
List<File> files = future.get();
36-
37-
traverser.shutdownThreadPool();
38-
39-
return files;
42+
return traverser.traverse(directoryPath);
4043
}
4144

4245
/**
43-
* Collects all top-level files from the specified directory, excluding any
44-
* files in subdirectories.
46+
* Collects the top-level files in a directory asynchronously.
47+
* <p>
48+
* This method retrieves the files located directly in the specified directory
49+
* without traversing its subdirectories. The operation is performed asynchronously,
50+
* and the result is returned as a `Future`.
4551
*
46-
* @param directoryPath the path of the directory to scan for top-level files
47-
* @return an Optional containing a list of top-level files found in the
48-
* directory,
49-
* or empty if no files are found
50-
* @throws ExecutionException if an error occurs during the asynchronous file
51-
* traversal
52-
* @throws InterruptedException if the thread executing the file traversal is
53-
* interrupted
52+
* @param directoryPath the directory to scan for top-level files
53+
* @return a Future containing the list of top-level files in the directory
5454
*/
55-
public final Optional<List<File>> collectTopLevelFiles(File directoryPath)
56-
throws ExecutionException, InterruptedException {
57-
58-
return Optional.of(PWSSDirectoryNavUtil.GetSelectedFolderWithoutSubFolders(directoryPath));
55+
@Async
56+
public Future<List<File>> collectTopLevelFiles(File directoryPath) {
57+
log.info("Starting asynchronous scan for top-level files in directory: {}", directoryPath);
58+
List<File> files = PWSSDirectoryNavUtil.GetSelectedFolderWithoutSubFolders(directoryPath);
59+
return CompletableFuture.completedFuture(files);
5960
}
60-
6161
}

File-Integrity-Scanner/src/main/java/org/pwss/file_integrity_scanner/component/FileHashComputer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public FileHashComputer() {
2424
* @param file the file for which hashes need to be computed
2525
* @return an object containing the computed hashes for the file
2626
*/
27-
public final HashForFilesOutput computeHashes(File file) {
27+
public HashForFilesOutput computeHashes(File file) {
2828
return fileHashHandler.GetAllHashes(file);
2929
}
3030
}

File-Integrity-Scanner/src/main/java/org/pwss/file_integrity_scanner/config/AppConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
import org.springframework.context.annotation.Primary;
1010
import org.springframework.scheduling.annotation.AsyncConfigurer;
1111
import org.springframework.scheduling.annotation.EnableAsync;
12+
import org.springframework.scheduling.annotation.EnableScheduling;
1213
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
1314

1415
@EnableAsync
16+
@EnableScheduling
1517
@Configuration
1618
public class AppConfig implements AsyncConfigurer {
1719

File-Integrity-Scanner/src/main/java/org/pwss/file_integrity_scanner/msr/domain/model/entities/monitored_directory/MonitoredDirectory.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ public class MonitoredDirectory {
3030
@Column(name = "baseline_established", nullable = false)
3131
private Boolean baselineEstablished = false;
3232

33+
@Column(name = "include_subdirectories", nullable = false)
34+
private Boolean includeSubdirectories = true;
35+
3336
// Getters and setters
3437

3538
public Integer getId() {
@@ -87,4 +90,12 @@ public Boolean getBaselineEstablished() {
8790
public void setBaselineEstablished(Boolean baselineEstablished) {
8891
this.baselineEstablished = baselineEstablished;
8992
}
93+
94+
public Boolean getIncludeSubdirectories() {
95+
return includeSubdirectories;
96+
}
97+
98+
public void setIncludeSubdirectories(Boolean includeSubdirectories) {
99+
this.includeSubdirectories = includeSubdirectories;
100+
}
90101
}

File-Integrity-Scanner/src/main/java/org/pwss/file_integrity_scanner/msr/service/monitored_directory/MonitoredDirectoryService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public interface MonitoredDirectoryService {
1717
*
1818
* @param isActive true to find active directories, false to find inactive ones
1919
* @return a list of monitored directories matching the specified active status,
20-
* or null if no matches are found or an error occurs
20+
* or null if no matches are found or an error occurs
2121
*/
2222
List<MonitoredDirectory> findByIsActive(boolean isActive);
2323

@@ -32,7 +32,7 @@ public interface MonitoredDirectoryService {
3232

3333
/**
3434
* Persists a monitored directory entity in the database.
35-
*
35+
* <p>
3636
* This method saves or updates the provided {@code MonitoredDirectory}
3737
* entity, ensuring its state is recorded persistently. It handles all
3838
* necessary operations to make the entity available for future queries.

File-Integrity-Scanner/src/main/java/org/pwss/file_integrity_scanner/msr/service/monitored_directory/MonitoredDirectoryServiceImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public List<MonitoredDirectory> findByIsActive(boolean isActive) {
3636

3737
@Override
3838
public void save(MonitoredDirectory mDirectory) {
39-
this.repository.save(mDirectory);
39+
this.repository.save(mDirectory);
4040
}
4141

4242
@Override

File-Integrity-Scanner/src/main/java/org/pwss/file_integrity_scanner/msr/service/scan/ScanService.java

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.pwss.file_integrity_scanner.msr.service.scan;
22

3-
import org.pwss.file_integrity_scanner.msr.domain.model.entities.scan.Scan;
3+
import org.pwss.file_integrity_scanner.msr.domain.model.entities.monitored_directory.MonitoredDirectory;
44

55
/**
66
* Service interface for managing directory scans.
@@ -17,26 +17,14 @@ public interface ScanService {
1717
void scanAllDirectories();
1818

1919
/**
20-
* Scans a monitored directory using the provided scan instance.
20+
* Initiates scanning of a single monitored directory.
21+
* <p>
22+
* This method starts the scanning process for the specified monitored directory.
23+
* It ensures that only the provided directory is scanned, rather than all monitored directories.
2124
*
22-
* This method is an overloaded variant that calls the two-parameter method with
23-
* default value set to true for
24-
* includeSubFolders.
25-
*
26-
* @param scanInstance the scan instance used for scanning the directory
27-
* @return true if the monitored directory scan is successful, false otherwise
28-
*/
29-
Boolean scanMonitoredDirectory(Scan scanInstance);
30-
31-
/**
32-
* Scans a monitored directory using the provided scan instance.
33-
*
34-
* @param scanInstance the scan instance used for scanning the directory
35-
* @param includeSubFolders whether to include subfolders in the scan (default
36-
* is false)
37-
* @return true if the monitored directory scan is successful, false otherwise
25+
* @param monitoredDirectory the monitored directory to be scanned
3826
*/
39-
Boolean scanMonitoredDirectory(Scan scanInstance, boolean includeSubFolders);
27+
void scanSingleDirectory(MonitoredDirectory monitoredDirectory);
4028

4129
/**
4230
* Stops any ongoing scans.

0 commit comments

Comments
 (0)