Skip to content

Commit 9898e63

Browse files
inv-jishnuypeckstadtbrfrn169
committed
Add util classes for data loader CLI (#2616)
Co-authored-by: Peckstadt Yves <[email protected]> Co-authored-by: Toshihiro Suzuki <[email protected]>
1 parent 1ec4208 commit 9898e63

File tree

7 files changed

+141
-12
lines changed

7 files changed

+141
-12
lines changed

core/src/main/java/com/scalar/db/common/error/CoreError.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,44 @@ public enum CoreError implements ScalarDbError {
788788
Category.USER_ERROR, "0186", "The CSV row: %s does not match header: %s.", "", ""),
789789
DATA_LOADER_JSON_CONTENT_START_ERROR(
790790
Category.USER_ERROR, "0187", "Expected JSON file content to be an array", "", ""),
791+
REPLICATION_NOT_ENABLED(
792+
Category.USER_ERROR,
793+
"0188",
794+
// TODO: Update the message once the licence type is determined.
795+
"The replication feature is not enabled. To use this feature, you must enable it",
796+
"",
797+
""),
798+
DATA_LOADER_IMPORT_TARGET_MISSING(
799+
Category.USER_ERROR,
800+
"0189",
801+
"Missing option: either '--namespace' and'--table' or '--control-file' options must be specified.",
802+
"",
803+
""),
804+
DATA_LOADER_MISSING_IMPORT_FILE(
805+
Category.USER_ERROR,
806+
"0190",
807+
"The file '%s' specified by the argument '%s' does not exist.",
808+
"",
809+
""),
810+
DATA_LOADER_LOG_DIRECTORY_WRITE_ACCESS_DENIED(
811+
Category.USER_ERROR, "0191", "Cannot write to the log directory: %s", "", ""),
812+
DATA_LOADER_LOG_DIRECTORY_CREATION_FAILED(
813+
Category.USER_ERROR, "0192", "Failed to create the log directory: %s", "", ""),
814+
DATA_LOADER_INVALID_CONTROL_FILE(
815+
Category.USER_ERROR, "0193", "Failed to parse the control file: %s", "", ""),
816+
DATA_LOADER_DIRECTORY_WRITE_ACCESS(
817+
Category.USER_ERROR,
818+
"0194",
819+
"No permission to create or write files in the directory: %s",
820+
"",
821+
""),
822+
DATA_LOADER_DIRECTORY_CREATION_FAILED(
823+
Category.USER_ERROR, "0195", "Failed to create the directory: %s", "", ""),
824+
DATA_LOADER_PATH_IS_NOT_A_DIRECTORY(
825+
Category.USER_ERROR, "0196", "Path exists but is not a directory: %s", "", ""),
826+
DATA_LOADER_FILE_PATH_IS_BLANK(
827+
Category.USER_ERROR, "0197", "File path must not be blank.", "", ""),
828+
DATA_LOADER_FILE_NOT_FOUND(Category.USER_ERROR, "0198", "File not found: %s", "", ""),
791829

792830
//
793831
// Errors for the concurrency error category

data-loader/cli/src/main/java/com/scalar/db/dataloader/cli/command/dataexport/ExportCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ private void validateOutputDirectory(@Nullable String path)
4949
private void validateDirectory(String directoryPath) throws DirectoryValidationException {
5050
// If the directory path is null or empty, use the current working directory
5151
if (directoryPath == null || directoryPath.isEmpty()) {
52-
DirectoryUtils.validateTargetDirectory(DirectoryUtils.getCurrentWorkingDirectory());
52+
DirectoryUtils.validateOrCreateTargetDirectory(DirectoryUtils.getCurrentWorkingDirectory());
5353
} else {
54-
DirectoryUtils.validateTargetDirectory(directoryPath);
54+
DirectoryUtils.validateOrCreateTargetDirectory(directoryPath);
5555
}
5656
}
5757

data-loader/cli/src/main/java/com/scalar/db/dataloader/cli/util/DirectoryUtils.java

100644100755
Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,30 @@ private DirectoryUtils() {
1515
// restrict instantiation
1616
}
1717

18+
/**
19+
* Validates the current working directory. Ensures that it is writable.
20+
*
21+
* @throws DirectoryValidationException if the current working directory is not writable
22+
*/
23+
public static void validateWorkingDirectory() throws DirectoryValidationException {
24+
Path workingDirectoryPath = Paths.get(System.getProperty("user.dir"));
25+
26+
// Check if the current working directory is writable
27+
if (!Files.isWritable(workingDirectoryPath)) {
28+
throw new DirectoryValidationException(
29+
CoreError.DATA_LOADER_DIRECTORY_WRITE_ACCESS.buildMessage(
30+
workingDirectoryPath.toAbsolutePath()));
31+
}
32+
}
33+
1834
/**
1935
* Validates the provided directory path. Ensures that the directory exists and is writable. If
2036
* the directory doesn't exist, a creation attempt is made.
2137
*
2238
* @param directoryPath the directory path to validate
2339
* @throws DirectoryValidationException if the directory is not writable or cannot be created
2440
*/
25-
public static void validateTargetDirectory(String directoryPath)
41+
public static void validateOrCreateTargetDirectory(String directoryPath)
2642
throws DirectoryValidationException {
2743
if (StringUtils.isBlank(directoryPath)) {
2844
throw new IllegalArgumentException(
@@ -32,7 +48,10 @@ public static void validateTargetDirectory(String directoryPath)
3248
Path path = Paths.get(directoryPath);
3349

3450
if (Files.exists(path)) {
35-
// Check if the provided directory is writable
51+
if (!Files.isDirectory(path)) {
52+
throw new DirectoryValidationException(
53+
CoreError.DATA_LOADER_PATH_IS_NOT_A_DIRECTORY.buildMessage(path));
54+
}
3655
if (!Files.isWritable(path)) {
3756
throw new DirectoryValidationException(
3857
CoreError.DATA_LOADER_DIRECTORY_WRITE_ACCESS_NOT_ALLOWED.buildMessage(
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.scalar.db.dataloader.cli.util;
2+
3+
import com.scalar.db.common.error.CoreError;
4+
import java.nio.file.Path;
5+
import java.nio.file.Paths;
6+
import org.apache.commons.lang3.StringUtils;
7+
8+
public class FileUtils {
9+
10+
/**
11+
* Validates the provided file path.
12+
*
13+
* @param filePath the file path to validate
14+
* @throws InvalidFilePathException if the file path is invalid
15+
*/
16+
public static void validateFilePath(String filePath) throws InvalidFilePathException {
17+
if (StringUtils.isBlank(filePath)) {
18+
throw new IllegalArgumentException(CoreError.DATA_LOADER_FILE_PATH_IS_BLANK.buildMessage());
19+
}
20+
Path pathToCheck = Paths.get(filePath);
21+
22+
if (!pathToCheck.toFile().exists()) {
23+
throw new InvalidFilePathException(
24+
CoreError.DATA_LOADER_FILE_NOT_FOUND.buildMessage(pathToCheck));
25+
}
26+
}
27+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.scalar.db.dataloader.cli.util;
2+
3+
public class InvalidFilePathException extends Exception {
4+
5+
public InvalidFilePathException(String message) {
6+
super(message);
7+
}
8+
9+
public InvalidFilePathException(String message, Throwable cause) {
10+
super(message, cause);
11+
}
12+
}

data-loader/cli/src/test/java/com/scalar/db/dataloader/cli/util/DirectoryUtilsTest.java

100644100755
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,26 @@ public void cleanup() throws IOException {
3030
@Test
3131
void validateTargetDirectory_ValidDirectory_NoExceptionThrown()
3232
throws DirectoryValidationException {
33-
DirectoryUtils.validateTargetDirectory(tempDir.toString());
33+
DirectoryUtils.validateOrCreateTargetDirectory(tempDir.toString());
3434
}
3535

3636
@Test
37-
void validateTargetDirectory_DirectoryDoesNotExist_CreatesDirectory()
37+
void validateOrCreateTargetDirectory_DirectoryDoesNotExist_CreatesDirectory()
3838
throws DirectoryValidationException {
3939
Path newDirectory = Paths.get(tempDir.toString(), "newDir");
40-
DirectoryUtils.validateTargetDirectory(newDirectory.toString());
40+
DirectoryUtils.validateOrCreateTargetDirectory(newDirectory.toString());
4141
assertTrue(Files.exists(newDirectory));
4242
}
4343

4444
@Test
45-
void validateTargetDirectory_DirectoryNotWritable_ThrowsException() throws IOException {
45+
void validateOrCreateTargetDirectory_DirectoryNotWritable_ThrowsException() throws IOException {
4646
Path readOnlyDirectory = Files.createDirectory(Paths.get(tempDir.toString(), "readOnlyDir"));
4747
readOnlyDirectory.toFile().setWritable(false);
4848

4949
assertThrows(
5050
DirectoryValidationException.class,
5151
() -> {
52-
DirectoryUtils.validateTargetDirectory(readOnlyDirectory.toString());
52+
DirectoryUtils.validateOrCreateTargetDirectory(readOnlyDirectory.toString());
5353
});
5454
}
5555

@@ -58,16 +58,16 @@ void validateTargetDirectory_NullDirectory_ThrowsException() {
5858
assertThrows(
5959
IllegalArgumentException.class,
6060
() -> {
61-
DirectoryUtils.validateTargetDirectory(null);
61+
DirectoryUtils.validateOrCreateTargetDirectory(null);
6262
});
6363
}
6464

6565
@Test
66-
void validateTargetDirectory_EmptyDirectory_ThrowsException() {
66+
void validateOrCreateTargetDirectory_EmptyDirectory_ThrowsException() {
6767
assertThrows(
6868
IllegalArgumentException.class,
6969
() -> {
70-
DirectoryUtils.validateTargetDirectory("");
70+
DirectoryUtils.validateOrCreateTargetDirectory("");
7171
});
7272
}
7373

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.scalar.db.dataloader.cli.util;
2+
3+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
4+
5+
import com.scalar.db.common.error.CoreError;
6+
import java.nio.file.Paths;
7+
import org.junit.jupiter.api.Test;
8+
9+
public class FileUtilsTest {
10+
11+
private static final String currentPath = Paths.get("").toAbsolutePath().toString();
12+
13+
@Test
14+
void validateFilePath_withValidFilePath_shouldNotThrowException()
15+
throws InvalidFilePathException {
16+
// Test and confirm no exception is thrown when a valid path is provided
17+
FileUtils.validateFilePath(currentPath);
18+
}
19+
20+
@Test
21+
void validateFilePath_withInvalidFilePath_shouldThrowException() {
22+
assertThatThrownBy(() -> FileUtils.validateFilePath(currentPath + "/demo"))
23+
.isInstanceOf(InvalidFilePathException.class)
24+
.hasMessage(CoreError.DATA_LOADER_FILE_NOT_FOUND.buildMessage(currentPath + "/demo"));
25+
}
26+
27+
@Test
28+
void validateFilePath_withBlankFilePath_shouldThrowException() {
29+
assertThatThrownBy(() -> FileUtils.validateFilePath(""))
30+
.isInstanceOf(IllegalArgumentException.class)
31+
.hasMessage(CoreError.DATA_LOADER_FILE_PATH_IS_BLANK.buildMessage());
32+
}
33+
}

0 commit comments

Comments
 (0)