Skip to content

Commit c7579d2

Browse files
Backport to branch(3.15) : Add util classes for data loader CLI (#2652)
Co-authored-by: inv-jishnu <[email protected]>
1 parent 62b738e commit c7579d2

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
@@ -848,6 +848,44 @@ public enum CoreError implements ScalarDbError {
848848
Category.USER_ERROR, "0186", "The CSV row: %s does not match header: %s.", "", ""),
849849
DATA_LOADER_JSON_CONTENT_START_ERROR(
850850
Category.USER_ERROR, "0187", "Expected JSON file content to be an array", "", ""),
851+
REPLICATION_NOT_ENABLED(
852+
Category.USER_ERROR,
853+
"0188",
854+
// TODO: Update the message once the licence type is determined.
855+
"The replication feature is not enabled. To use this feature, you must enable it",
856+
"",
857+
""),
858+
DATA_LOADER_IMPORT_TARGET_MISSING(
859+
Category.USER_ERROR,
860+
"0189",
861+
"Missing option: either '--namespace' and'--table' or '--control-file' options must be specified.",
862+
"",
863+
""),
864+
DATA_LOADER_MISSING_IMPORT_FILE(
865+
Category.USER_ERROR,
866+
"0190",
867+
"The file '%s' specified by the argument '%s' does not exist.",
868+
"",
869+
""),
870+
DATA_LOADER_LOG_DIRECTORY_WRITE_ACCESS_DENIED(
871+
Category.USER_ERROR, "0191", "Cannot write to the log directory: %s", "", ""),
872+
DATA_LOADER_LOG_DIRECTORY_CREATION_FAILED(
873+
Category.USER_ERROR, "0192", "Failed to create the log directory: %s", "", ""),
874+
DATA_LOADER_INVALID_CONTROL_FILE(
875+
Category.USER_ERROR, "0193", "Failed to parse the control file: %s", "", ""),
876+
DATA_LOADER_DIRECTORY_WRITE_ACCESS(
877+
Category.USER_ERROR,
878+
"0194",
879+
"No permission to create or write files in the directory: %s",
880+
"",
881+
""),
882+
DATA_LOADER_DIRECTORY_CREATION_FAILED(
883+
Category.USER_ERROR, "0195", "Failed to create the directory: %s", "", ""),
884+
DATA_LOADER_PATH_IS_NOT_A_DIRECTORY(
885+
Category.USER_ERROR, "0196", "Path exists but is not a directory: %s", "", ""),
886+
DATA_LOADER_FILE_PATH_IS_BLANK(
887+
Category.USER_ERROR, "0197", "File path must not be blank.", "", ""),
888+
DATA_LOADER_FILE_NOT_FOUND(Category.USER_ERROR, "0198", "File not found: %s", "", ""),
851889

852890
//
853891
// 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)