Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions core/src/main/java/com/scalar/db/common/error/CoreError.java
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,44 @@ public enum CoreError implements ScalarDbError {
Category.USER_ERROR, "0186", "The CSV row: %s does not match header: %s.", "", ""),
DATA_LOADER_JSON_CONTENT_START_ERROR(
Category.USER_ERROR, "0187", "Expected JSON file content to be an array", "", ""),
REPLICATION_NOT_ENABLED(
Category.USER_ERROR,
"0188",
// TODO: Update the message once the licence type is determined.
"The replication feature is not enabled. To use this feature, you must enable it",
"",
""),
DATA_LOADER_IMPORT_TARGET_MISSING(
Category.USER_ERROR,
"0189",
"Missing option: either '--namespace' and'--table' or '--control-file' options must be specified.",
"",
""),
DATA_LOADER_MISSING_IMPORT_FILE(
Category.USER_ERROR,
"0190",
"The file '%s' specified by the argument '%s' does not exist.",
"",
""),
DATA_LOADER_LOG_DIRECTORY_WRITE_ACCESS_DENIED(
Category.USER_ERROR, "0191", "Cannot write to the log directory: %s", "", ""),
DATA_LOADER_LOG_DIRECTORY_CREATION_FAILED(
Category.USER_ERROR, "0192", "Failed to create the log directory: %s", "", ""),
DATA_LOADER_INVALID_CONTROL_FILE(
Category.USER_ERROR, "0193", "Failed to parse the control file: %s", "", ""),
DATA_LOADER_DIRECTORY_WRITE_ACCESS(
Category.USER_ERROR,
"0194",
"No permission to create or write files in the directory: %s",
"",
""),
DATA_LOADER_DIRECTORY_CREATION_FAILED(
Category.USER_ERROR, "0195", "Failed to create the directory: %s", "", ""),
DATA_LOADER_PATH_IS_NOT_A_DIRECTORY(
Category.USER_ERROR, "0196", "Path exists but is not a directory: %s", "", ""),
DATA_LOADER_FILE_PATH_IS_BLANK(
Category.USER_ERROR, "0197", "File path must not be blank.", "", ""),
DATA_LOADER_FILE_NOT_FOUND(Category.USER_ERROR, "0198", "File not found: %s", "", ""),

//
// Errors for the concurrency error category
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ private void validateOutputDirectory(@Nullable String path)
private void validateDirectory(String directoryPath) throws DirectoryValidationException {
// If the directory path is null or empty, use the current working directory
if (directoryPath == null || directoryPath.isEmpty()) {
DirectoryUtils.validateTargetDirectory(DirectoryUtils.getCurrentWorkingDirectory());
DirectoryUtils.validateOrCreateTargetDirectory(DirectoryUtils.getCurrentWorkingDirectory());
} else {
DirectoryUtils.validateTargetDirectory(directoryPath);
DirectoryUtils.validateOrCreateTargetDirectory(directoryPath);
}
}

Expand Down
23 changes: 21 additions & 2 deletions data-loader/cli/src/main/java/com/scalar/db/dataloader/cli/util/DirectoryUtils.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,30 @@ private DirectoryUtils() {
// restrict instantiation
}

/**
* Validates the current working directory. Ensures that it is writable.
*
* @throws DirectoryValidationException if the current working directory is not writable
*/
public static void validateWorkingDirectory() throws DirectoryValidationException {
Path workingDirectoryPath = Paths.get(System.getProperty("user.dir"));

// Check if the current working directory is writable
if (!Files.isWritable(workingDirectoryPath)) {
throw new DirectoryValidationException(
CoreError.DATA_LOADER_DIRECTORY_WRITE_ACCESS.buildMessage(
workingDirectoryPath.toAbsolutePath()));
}
}

/**
* Validates the provided directory path. Ensures that the directory exists and is writable. If
* the directory doesn't exist, a creation attempt is made.
*
* @param directoryPath the directory path to validate
* @throws DirectoryValidationException if the directory is not writable or cannot be created
*/
public static void validateTargetDirectory(String directoryPath)
public static void validateOrCreateTargetDirectory(String directoryPath)
throws DirectoryValidationException {
if (StringUtils.isBlank(directoryPath)) {
throw new IllegalArgumentException(
Expand All @@ -32,7 +48,10 @@ public static void validateTargetDirectory(String directoryPath)
Path path = Paths.get(directoryPath);

if (Files.exists(path)) {
// Check if the provided directory is writable
if (!Files.isDirectory(path)) {
throw new DirectoryValidationException(
CoreError.DATA_LOADER_PATH_IS_NOT_A_DIRECTORY.buildMessage(path));
}
if (!Files.isWritable(path)) {
throw new DirectoryValidationException(
CoreError.DATA_LOADER_DIRECTORY_WRITE_ACCESS_NOT_ALLOWED.buildMessage(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.scalar.db.dataloader.cli.util;

import com.scalar.db.common.error.CoreError;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.lang3.StringUtils;

public class FileUtils {

/**
* Validates the provided file path.
*
* @param filePath the file path to validate
* @throws InvalidFilePathException if the file path is invalid
*/
public static void validateFilePath(String filePath) throws InvalidFilePathException {
if (StringUtils.isBlank(filePath)) {
throw new IllegalArgumentException(CoreError.DATA_LOADER_FILE_PATH_IS_BLANK.buildMessage());
}
Path pathToCheck = Paths.get(filePath);

if (!pathToCheck.toFile().exists()) {
throw new InvalidFilePathException(
CoreError.DATA_LOADER_FILE_NOT_FOUND.buildMessage(pathToCheck));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.scalar.db.dataloader.cli.util;

public class InvalidFilePathException extends Exception {

public InvalidFilePathException(String message) {
super(message);
}

public InvalidFilePathException(String message, Throwable cause) {
super(message, cause);
}
}
16 changes: 8 additions & 8 deletions data-loader/cli/src/test/java/com/scalar/db/dataloader/cli/util/DirectoryUtilsTest.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,26 @@ public void cleanup() throws IOException {
@Test
void validateTargetDirectory_ValidDirectory_NoExceptionThrown()
throws DirectoryValidationException {
DirectoryUtils.validateTargetDirectory(tempDir.toString());
DirectoryUtils.validateOrCreateTargetDirectory(tempDir.toString());
}

@Test
void validateTargetDirectory_DirectoryDoesNotExist_CreatesDirectory()
void validateOrCreateTargetDirectory_DirectoryDoesNotExist_CreatesDirectory()
throws DirectoryValidationException {
Path newDirectory = Paths.get(tempDir.toString(), "newDir");
DirectoryUtils.validateTargetDirectory(newDirectory.toString());
DirectoryUtils.validateOrCreateTargetDirectory(newDirectory.toString());
assertTrue(Files.exists(newDirectory));
}

@Test
void validateTargetDirectory_DirectoryNotWritable_ThrowsException() throws IOException {
void validateOrCreateTargetDirectory_DirectoryNotWritable_ThrowsException() throws IOException {
Path readOnlyDirectory = Files.createDirectory(Paths.get(tempDir.toString(), "readOnlyDir"));
readOnlyDirectory.toFile().setWritable(false);

assertThrows(
DirectoryValidationException.class,
() -> {
DirectoryUtils.validateTargetDirectory(readOnlyDirectory.toString());
DirectoryUtils.validateOrCreateTargetDirectory(readOnlyDirectory.toString());
});
}

Expand All @@ -58,16 +58,16 @@ void validateTargetDirectory_NullDirectory_ThrowsException() {
assertThrows(
IllegalArgumentException.class,
() -> {
DirectoryUtils.validateTargetDirectory(null);
DirectoryUtils.validateOrCreateTargetDirectory(null);
});
}

@Test
void validateTargetDirectory_EmptyDirectory_ThrowsException() {
void validateOrCreateTargetDirectory_EmptyDirectory_ThrowsException() {
assertThrows(
IllegalArgumentException.class,
() -> {
DirectoryUtils.validateTargetDirectory("");
DirectoryUtils.validateOrCreateTargetDirectory("");
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.scalar.db.dataloader.cli.util;

import static org.assertj.core.api.Assertions.assertThatThrownBy;

import com.scalar.db.common.error.CoreError;
import java.nio.file.Paths;
import org.junit.jupiter.api.Test;

public class FileUtilsTest {

private static final String currentPath = Paths.get("").toAbsolutePath().toString();

@Test
void validateFilePath_withValidFilePath_shouldNotThrowException()
throws InvalidFilePathException {
// Test and confirm no exception is thrown when a valid path is provided
FileUtils.validateFilePath(currentPath);
}

@Test
void validateFilePath_withInvalidFilePath_shouldThrowException() {
assertThatThrownBy(() -> FileUtils.validateFilePath(currentPath + "/demo"))
.isInstanceOf(InvalidFilePathException.class)
.hasMessage(CoreError.DATA_LOADER_FILE_NOT_FOUND.buildMessage(currentPath + "/demo"));
}

@Test
void validateFilePath_withBlankFilePath_shouldThrowException() {
assertThatThrownBy(() -> FileUtils.validateFilePath(""))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage(CoreError.DATA_LOADER_FILE_PATH_IS_BLANK.buildMessage());
}
}