diff --git a/src/main/java/com/skyflow/VaultClient.java b/src/main/java/com/skyflow/VaultClient.java index 7536a2c1..34c99d3e 100644 --- a/src/main/java/com/skyflow/VaultClient.java +++ b/src/main/java/com/skyflow/VaultClient.java @@ -24,19 +24,21 @@ import com.skyflow.generated.rest.resources.tokens.TokensClient; import com.skyflow.generated.rest.resources.tokens.requests.V1DetokenizePayload; import com.skyflow.generated.rest.resources.tokens.requests.V1TokenizePayload; -import com.skyflow.generated.rest.types.*; import com.skyflow.generated.rest.types.Transformations; +import com.skyflow.generated.rest.types.*; +import com.skyflow.logs.ErrorLogs; import com.skyflow.logs.InfoLogs; import com.skyflow.serviceaccount.util.Token; import com.skyflow.utils.Constants; import com.skyflow.utils.Utils; import com.skyflow.utils.logger.LogUtil; import com.skyflow.utils.validations.Validations; +import com.skyflow.vault.data.FileUploadRequest; import com.skyflow.vault.data.InsertRequest; import com.skyflow.vault.data.UpdateRequest; -import com.skyflow.vault.detect.*; import com.skyflow.vault.detect.DeidentifyFileRequest; import com.skyflow.vault.detect.DeidentifyTextRequest; +import com.skyflow.vault.detect.*; import com.skyflow.vault.tokens.ColumnValue; import com.skyflow.vault.tokens.DetokenizeData; import com.skyflow.vault.tokens.DetokenizeRequest; @@ -44,6 +46,9 @@ import io.github.cdimascio.dotenv.Dotenv; import io.github.cdimascio.dotenv.DotenvException; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.*; import java.util.stream.Collectors; @@ -78,7 +83,7 @@ protected StringsClient getDetectTextApi() { return this.apiClient.strings(); } - protected FilesClient getDetectFileAPi(){ + protected FilesClient getDetectFileAPi() { return this.apiClient.files(); } @@ -209,12 +214,41 @@ protected V1TokenizePayload getTokenizePayload(TokenizeRequest request) { return payloadBuilder.build(); } + protected File getUploadFileColumnName(FileUploadRequest request) throws SkyflowException { + if (request.getBase64() != null) { + try { + byte[] decodedBytes = Base64.getDecoder().decode(request.getBase64()); + File tempFile = new File(System.getProperty("java.io.tmpdir"), request.getFileName()); + if (tempFile.exists()) { + boolean isDeleted = tempFile.delete(); + } + boolean isCreated = tempFile.createNewFile(); + try (FileOutputStream fos = new FileOutputStream(tempFile)) { + fos.write(decodedBytes); + } + return tempFile; + } catch (Exception e) { + LogUtil.printErrorLog(ErrorLogs.INVALID_BASE64_IN_FILE_UPLOAD.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidBase64InFileUpload.getMessage()); + } + } else if (request.getFilePath() != null) { + File file = new File(request.getFilePath()); + if (!file.exists()) { + LogUtil.printErrorLog(ErrorLogs.INVALID_FILE_PATH_IN_FILE_UPLOAD.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidFilePath.getMessage()); + } + return file; + } else if (request.getFileObject() != null) { + return request.getFileObject(); + } else return null; + } + protected void setBearerToken() throws SkyflowException { prioritiseCredentials(); Validations.validateCredentials(this.finalCredentials); if (this.finalCredentials.getApiKey() != null) { LogUtil.printInfoLog(InfoLogs.REUSE_API_KEY.getLog()); - token=this.finalCredentials.getApiKey(); + token = this.finalCredentials.getApiKey(); } else if (Token.isExpired(token)) { LogUtil.printInfoLog(InfoLogs.BEARER_TOKEN_EXPIRED.getLog()); token = Utils.generateBearerToken(this.finalCredentials); @@ -334,7 +368,6 @@ protected ReidentifyStringRequest getReidentifyStringRequest(ReidentifyTextReque .build(); } - private EntityInfo convertDetectedEntityToEntityInfo(DetectedEntity detectedEntity) { TextIndex textIndex = new TextIndex( detectedEntity.getLocation().get().getStartIndex().orElse(0), @@ -387,7 +420,7 @@ private Transformations getTransformations(com.skyflow.vault.detect.Transformati .build(); } - private List getEntityTypes(List entities){ + private List getEntityTypes(List entities) { List mappedEntityTypes = null; if (entities != null) { mappedEntityTypes = entities.stream() @@ -398,7 +431,7 @@ private List getEntityTypes(List entities){ return mappedEntityTypes; } - protected com.skyflow.generated.rest.resources.files.requests.DeidentifyTextRequest getDeidentifyTextFileRequest(DeidentifyFileRequest request, String vaultId, String base64Content){ + protected com.skyflow.generated.rest.resources.files.requests.DeidentifyTextRequest getDeidentifyTextFileRequest(DeidentifyFileRequest request, String vaultId, String base64Content) { List mappedEntityTypes = getEntityTypes(request.getEntities()); TokenFormat tokenFormat = request.getTokenFormat(); diff --git a/src/main/java/com/skyflow/errors/ErrorMessage.java b/src/main/java/com/skyflow/errors/ErrorMessage.java index df075bca..7d19106b 100644 --- a/src/main/java/com/skyflow/errors/ErrorMessage.java +++ b/src/main/java/com/skyflow/errors/ErrorMessage.java @@ -114,6 +114,21 @@ public enum ErrorMessage { ColumnValuesKeyErrorTokenize("%s0 Validation error. 'columnValues' key is missing from the payload. Specify a 'columnValues' key."), EmptyColumnGroupInColumnValue("%s0 Validation error. Invalid column group in column value. Specify a valid column group."), + // Upload file + InvalidFileUploadRequest("%s0 Validation error. Invalid file upload request. Specify a valid file upload request."), + TableNameKeyError("%s0 Validation error. 'tableName' key is missing from the payload. Specify a 'tableName' key."), + EmptyTableName("%s0 Validation error. 'tableName' can't be empty. Specify a table name."), + SkyflowIdKeyErrorInFileUpload("%s0 Validation error. 'skyflowId' key is missing from the payload. Specify a 'skyflowId' key."), + EmptySkyflowIdInFileUpload("%s0 Validation error. 'skyflowId' can't be empty. Specify a skyflow id."), + ColumnNameKeyErrorInFileUpload("%s0 Validation error. 'columnName' can't be empty. Specify a 'columnName' key."), + EmptyColumnNameInFileUpload("%s0 Validation error. 'columnName' can't be empty. Specify a column name."), + MissingFileSourceInFileUpload("%s0 Validation error. Provide exactly one of filePath, base64, or fileObject."), + MultipleFileSourcesInFileUpload("%s0 Validation error. Provide exactly one of filePath, base64, or fileObject."), + EmptyFilePathInFileUpload("%s0 Validation error. File path cannot be empty in file upload request. Specify a valid file path."), + MissingFileNameForBase64("%s0 Validation error. File name is required when providing a base64 string"), + InvalidFileObjectInFileUpload("%s0 Validation error. Invalid file object in file upload request. Specify a valid file object."), + InvalidBase64InFileUpload("%s0 Validation error. Invalid base64 string in file upload request. Specify a valid base64 string."), + // Connection InvalidRequestHeaders("%s0 Validation error. Request headers aren't valid. Specify valid request headers."), EmptyRequestHeaders("%s0 Validation error. Request headers are empty. Specify valid request headers."), @@ -148,8 +163,7 @@ public enum ErrorMessage { FailedtoSaveProcessedFile("%s0 Validation error. Failed to save the processed file. Ensure the output directory is valid and writable."), InvalidAudioFileType("%s0 Validation error. The file type is not supported. Specify a valid file type mp3 or wav."), // Generic - ErrorOccurred("%s0 API error. Error occurred.") - ; + ErrorOccurred("%s0 API error. Error occurred."); private final String message; ErrorMessage(String message) { diff --git a/src/main/java/com/skyflow/logs/ErrorLogs.java b/src/main/java/com/skyflow/logs/ErrorLogs.java index 3415860c..87f120f3 100644 --- a/src/main/java/com/skyflow/logs/ErrorLogs.java +++ b/src/main/java/com/skyflow/logs/ErrorLogs.java @@ -96,7 +96,17 @@ public enum ErrorLogs { EMPTY_OR_NULL_COLUMN_GROUP_IN_COLUMN_VALUES("Invalid %s1 request. Column group can not be null or empty in column values at index %s2."), TOKENIZE_REQUEST_REJECTED("Tokenize request resulted in failure."), DELETE_REQUEST_REJECTED("Delete request resulted in failure."), + FILE_UPLOAD_REQUEST_REJECTED("File upload request resulted in failure."), + INVALID_FILE_UPLOAD_REQUEST("Invalid %s1 request. Invalid file upload request. Specify a valid file upload request."), + COLUMN_NAME_IS_REQUIRED_IN_FILE_UPLOAD("Invalid %s1 request. Column name is required."), + INVALID_FILE_SOURCES_IN_FILE_UPLOAD("Invalid %s1 request. Exactly one of 'filePath', 'base64', or 'fileObject' is required."), + MISSING_FILE_PATH_IN_FILE_UPLOAD("Invalid %s1 request. File path cannot be empty in file upload request. Specify a valid file path as string."), + MISSING_FILE_NAME_FOR_BASE64("Invalid %s1 request. File name is required when providing a base64 string"), + INVALID_FILE_OBJECT_IN_FILE_UPLOAD("Invalid %s1 request. Invalid file object in file upload request. Specify a valid file object."), + INVALID_FILE_PATH_IN_FILE_UPLOAD("Invalid %s1 request. Invalid file path in file upload request. Specify a valid file path."), + INVALID_BASE64_IN_FILE_UPLOAD("Invalid %s1 request. Invalid base64 string in file upload request. Specify a valid base64 string."), + // invoke connection interface INVOKE_CONNECTION_INVALID_CONNECTION_URL("Invalid %s1 request. Connection URL is not a valid URL."), EMPTY_REQUEST_HEADERS("Invalid %s1 request. Request headers can not be empty."), diff --git a/src/main/java/com/skyflow/logs/InfoLogs.java b/src/main/java/com/skyflow/logs/InfoLogs.java index efd81a49..3cd4c911 100644 --- a/src/main/java/com/skyflow/logs/InfoLogs.java +++ b/src/main/java/com/skyflow/logs/InfoLogs.java @@ -69,6 +69,11 @@ public enum InfoLogs { TOKENIZE_REQUEST_RESOLVED("Tokenize request resolved."), TOKENIZE_SUCCESS("Data tokenized."), + // File upload interface + FILE_UPLOAD_TRIGGERED("File upload method triggered."), + VALIDATE_FILE_UPLOAD_REQUEST("Validating file upload request."), + FILE_UPLOAD_REQUEST_RESOLVED("File upload request resolved."), + FILE_UPLOAD_SUCCESS("File uploaded successfully."), // Invoke connection interface INVOKE_CONNECTION_TRIGGERED("Invoke connection method triggered."), diff --git a/src/main/java/com/skyflow/utils/validations/Validations.java b/src/main/java/com/skyflow/utils/validations/Validations.java index 841c03b6..4c14c170 100644 --- a/src/main/java/com/skyflow/utils/validations/Validations.java +++ b/src/main/java/com/skyflow/utils/validations/Validations.java @@ -17,7 +17,10 @@ import com.skyflow.utils.logger.LogUtil; import com.skyflow.vault.connection.InvokeConnectionRequest; import com.skyflow.vault.data.*; -import com.skyflow.vault.detect.*; +import com.skyflow.vault.detect.DeidentifyFileRequest; +import com.skyflow.vault.detect.DeidentifyTextRequest; +import com.skyflow.vault.detect.GetDetectRunRequest; +import com.skyflow.vault.detect.ReidentifyTextRequest; import com.skyflow.vault.tokens.ColumnValue; import com.skyflow.vault.tokens.DetokenizeData; import com.skyflow.vault.tokens.DetokenizeRequest; @@ -185,12 +188,12 @@ public static void validateCredentials(Credentials credentials) throws SkyflowEx LogUtil.printErrorLog(ErrorLogs.EMPTY_API_KEY_VALUE.getLog()); throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyApikey.getMessage()); } else { - Pattern pattern = Pattern.compile(Constants.API_KEY_REGEX); - Matcher matcher = pattern.matcher(apiKey); - if (!matcher.matches()) { - LogUtil.printErrorLog(ErrorLogs.INVALID_API_KEY.getLog()); - throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidApikey.getMessage()); - } + Pattern pattern = Pattern.compile(Constants.API_KEY_REGEX); + Matcher matcher = pattern.matcher(apiKey); + if (!matcher.matches()) { + LogUtil.printErrorLog(ErrorLogs.INVALID_API_KEY.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidApikey.getMessage()); + } } } else if (roles != null) { if (roles.isEmpty()) { @@ -709,6 +712,106 @@ public static void validateReidentifyTextRequest(ReidentifyTextRequest reidentif } } + public static void validateFileUploadRequest(FileUploadRequest fileUploadRequest) throws SkyflowException { + if (fileUploadRequest == null) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.INVALID_FILE_UPLOAD_REQUEST.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidFileUploadRequest.getMessage()); + } + + String tableName = fileUploadRequest.getTableName(); + String skyflowId = fileUploadRequest.getSkyflowId(); + String columnName = fileUploadRequest.getColumnName(); + + if (tableName == null) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.TABLE_IS_REQUIRED.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.TableNameKeyError.getMessage()); + } else if (tableName.trim().isEmpty()) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.EMPTY_TABLE_NAME.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyTableName.getMessage()); + } + + if (skyflowId == null) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.SKYFLOW_ID_IS_REQUIRED.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.SkyflowIdKeyErrorInFileUpload.getMessage()); + } else if (skyflowId.trim().isEmpty()) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.EMPTY_SKYFLOW_ID.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptySkyflowIdInFileUpload.getMessage()); + } + + if (columnName == null) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.COLUMN_NAME_IS_REQUIRED_IN_FILE_UPLOAD.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.ColumnNameKeyErrorInFileUpload.getMessage()); + } else if (columnName.trim().isEmpty()) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.EMPTY_COLUMN_NAME.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyColumnNameInFileUpload.getMessage()); + } + + // Validate file source - at least one must be provided + String filePath = fileUploadRequest.getFilePath(); + String base64 = fileUploadRequest.getBase64(); + File fileObject = fileUploadRequest.getFileObject(); + + int validSources = 0; + if (filePath != null) validSources++; + if (base64 != null && !base64.trim().isEmpty()) validSources++; + if (fileObject != null) validSources++; + + if (validSources == 0) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.INVALID_FILE_SOURCES_IN_FILE_UPLOAD.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.MissingFileSourceInFileUpload.getMessage()); + } else if (validSources > 1) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.INVALID_FILE_SOURCES_IN_FILE_UPLOAD.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.MultipleFileSourcesInFileUpload.getMessage()); + } + + // Validate filePath if provided + if (filePath != null && filePath.trim().isEmpty()) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.MISSING_FILE_PATH_IN_FILE_UPLOAD.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyFilePathInFileUpload.getMessage()); + } + + // Validate fileName if base64 is provided + if (base64 != null && !base64.trim().isEmpty()) { + String fileName = fileUploadRequest.getFileName(); + if (fileName == null || fileName.trim().isEmpty()) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.MISSING_FILE_NAME_FOR_BASE64.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.MissingFileNameForBase64.getMessage()); + } + } + + // Validate fileObject if provided + if (fileObject != null) { + if (!fileObject.exists() || !fileObject.isFile()) { + LogUtil.printErrorLog(Utils.parameterizedString( + ErrorLogs.INVALID_FILE_OBJECT_IN_FILE_UPLOAD.getLog(), InterfaceName.FILE_UPLOAD.getName() + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidFileObjectInFileUpload.getMessage()); + } + } + } + private static boolean isInvalidURL(String configURL) { try { URL url = new URL(configURL); @@ -802,7 +905,7 @@ public static void validateDeidentifyFileRequest(DeidentifyFileRequest request) throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.BothFileAndFilePathProvided.getMessage()); } - if (filePath != null && filePath.trim().isEmpty()){ + if (filePath != null && filePath.trim().isEmpty()) { throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidFilePath.getMessage()); } @@ -838,7 +941,7 @@ public static void validateDeidentifyFileRequest(DeidentifyFileRequest request) if (request.getBleep() != null) { if (request.getBleep().getFrequency() == null || request.getBleep().getFrequency() <= 0) { LogUtil.printErrorLog(Utils.parameterizedString( - ErrorLogs.INVALID_BLEEP_TO_DEIDENTIFY_AUDIO.getLog(), InterfaceName.DETECT.getName() + ErrorLogs.INVALID_BLEEP_TO_DEIDENTIFY_AUDIO.getLog(), InterfaceName.DETECT.getName() )); throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidRequestBody.getMessage()); } @@ -858,13 +961,13 @@ public static void validateDeidentifyFileRequest(DeidentifyFileRequest request) File outDir = new File(request.getOutputDirectory()); if (!outDir.exists() || !outDir.isDirectory()) { LogUtil.printErrorLog(Utils.parameterizedString( - ErrorLogs.OUTPUT_DIRECTORY_NOT_FOUND.getLog(), InterfaceName.DETECT.getName() + ErrorLogs.OUTPUT_DIRECTORY_NOT_FOUND.getLog(), InterfaceName.DETECT.getName() )); throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.OutputDirectoryNotFound.getMessage()); } if (!outDir.canWrite()) { LogUtil.printErrorLog(Utils.parameterizedString( - ErrorLogs.INVALID_PERMISSIONS_FOR_OUTPUT_DIRECTORY.getLog(), InterfaceName.DETECT.getName() + ErrorLogs.INVALID_PERMISSIONS_FOR_OUTPUT_DIRECTORY.getLog(), InterfaceName.DETECT.getName() )); throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidPermission.getMessage()); } @@ -874,7 +977,7 @@ public static void validateDeidentifyFileRequest(DeidentifyFileRequest request) if (request.getWaitTime() != null && request.getWaitTime() <= 0) { throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidWaitTime.getMessage()); } - if(request.getWaitTime() > 64) { + if (request.getWaitTime() > 64) { throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.WaitTimeExceedsLimit.getMessage()); } } diff --git a/src/main/java/com/skyflow/vault/controller/VaultController.java b/src/main/java/com/skyflow/vault/controller/VaultController.java index 84e528b0..e15e4037 100644 --- a/src/main/java/com/skyflow/vault/controller/VaultController.java +++ b/src/main/java/com/skyflow/vault/controller/VaultController.java @@ -22,6 +22,8 @@ import com.skyflow.utils.validations.Validations; import com.skyflow.vault.data.*; import com.skyflow.vault.tokens.*; + +import java.io.File; import java.util.*; public final class VaultController extends VaultClient { @@ -359,4 +361,28 @@ public TokenizeResponse tokenize(TokenizeRequest tokenizeRequest) throws Skyflow LogUtil.printInfoLog(InfoLogs.TOKENIZE_SUCCESS.getLog()); return new TokenizeResponse(list); } + + public FileUploadResponse uploadFile(FileUploadRequest request) throws SkyflowException { + LogUtil.printInfoLog(InfoLogs.FILE_UPLOAD_TRIGGERED.getLog()); + V1UpdateRecordResponse result = null; + try { + LogUtil.printInfoLog(InfoLogs.VALIDATE_FILE_UPLOAD_REQUEST.getLog()); + Validations.validateFileUploadRequest(request); + setBearerToken(); + File fileColumnName = super.getUploadFileColumnName(request); + result = super.getRecordsApi().fileServiceUploadFile( + super.getVaultConfig().getVaultId(), + request.getTableName(), + request.getSkyflowId(), + Optional.ofNullable(fileColumnName) + ); + LogUtil.printInfoLog(InfoLogs.FILE_UPLOAD_REQUEST_RESOLVED.getLog()); + } catch (ApiClientApiException e) { + String bodyString = gson.toJson(e.body()); + LogUtil.printErrorLog(ErrorLogs.FILE_UPLOAD_REQUEST_REJECTED.getLog()); + throw new SkyflowException(e.statusCode(), e, e.headers(), bodyString); + } + LogUtil.printInfoLog(InfoLogs.FILE_UPLOAD_SUCCESS.getLog()); + return new FileUploadResponse(result.getSkyflowId().isPresent() ? result.getSkyflowId().get() : null); + } } diff --git a/src/main/java/com/skyflow/vault/data/FileUploadRequest.java b/src/main/java/com/skyflow/vault/data/FileUploadRequest.java new file mode 100644 index 00000000..b39c4705 --- /dev/null +++ b/src/main/java/com/skyflow/vault/data/FileUploadRequest.java @@ -0,0 +1,95 @@ +package com.skyflow.vault.data; + +import java.io.File; + +public class FileUploadRequest { + private final FileUploadRequestBuilder builder; + + private FileUploadRequest(FileUploadRequestBuilder builder) { + this.builder = builder; + } + + public static FileUploadRequestBuilder builder() { + return new FileUploadRequestBuilder(); + } + + public String getTableName() { + return this.builder.tableName; + } + + public String getColumnName() { + return this.builder.columnName; + } + + public String getSkyflowId() { + return this.builder.skyflowId; + } + + public String getFilePath() { + return this.builder.filePath; + } + + public String getBase64() { + return this.builder.base64; + } + + public File getFileObject() { + return this.builder.fileObject; + } + + public String getFileName() { + return this.builder.fileName; + } + + public static final class FileUploadRequestBuilder { + private String tableName; + private String columnName; + private String skyflowId; + private String filePath; + private String base64; + private File fileObject; + private String fileName; + + private FileUploadRequestBuilder() { + } + + public FileUploadRequestBuilder tableName(String tableName) { + this.tableName = tableName; + return this; + } + + public FileUploadRequestBuilder columnName(String columnName) { + this.columnName = columnName; + return this; + } + + public FileUploadRequestBuilder skyflowId(String skyflowId) { + this.skyflowId = skyflowId; + return this; + } + + public FileUploadRequestBuilder filePath(String filePath) { + this.filePath = filePath; + return this; + } + + public FileUploadRequestBuilder base64(String base64) { + this.base64 = base64; + return this; + } + + public FileUploadRequestBuilder fileObject(File fileObject) { + this.fileObject = fileObject; + return this; + } + + public FileUploadRequestBuilder fileName(String fileName) { + this.fileName = fileName; + return this; + } + + public FileUploadRequest build() { + return new FileUploadRequest(this); + } + } +} diff --git a/src/main/java/com/skyflow/vault/data/FileUploadResponse.java b/src/main/java/com/skyflow/vault/data/FileUploadResponse.java new file mode 100644 index 00000000..03bff12b --- /dev/null +++ b/src/main/java/com/skyflow/vault/data/FileUploadResponse.java @@ -0,0 +1,23 @@ +package com.skyflow.vault.data; + +import com.google.gson.*; + +public class FileUploadResponse { + private final String skyflowId; + + public FileUploadResponse(String skyflowId) { + this.skyflowId = skyflowId; + } + + public String getSkyflowId() { + return skyflowId; + } + + @Override + public String toString() { + Gson gson = new GsonBuilder().serializeNulls().create(); + JsonObject responseObject = gson.toJsonTree(this).getAsJsonObject(); + responseObject.add("errors", null); + return responseObject.toString(); + } +} diff --git a/src/test/java/com/skyflow/VaultClientTests.java b/src/test/java/com/skyflow/VaultClientTests.java index 1ebb1b23..75cba025 100644 --- a/src/test/java/com/skyflow/VaultClientTests.java +++ b/src/test/java/com/skyflow/VaultClientTests.java @@ -4,6 +4,7 @@ import com.skyflow.config.VaultConfig; import com.skyflow.enums.*; import com.skyflow.errors.ErrorCode; +import com.skyflow.errors.ErrorMessage; import com.skyflow.errors.SkyflowException; import com.skyflow.generated.rest.resources.files.FilesClient; import com.skyflow.generated.rest.resources.files.requests.*; @@ -22,11 +23,14 @@ import com.skyflow.generated.rest.types.DetectedEntity; import com.skyflow.generated.rest.types.EntityLocation; import com.skyflow.generated.rest.types.V1Byot; +import com.skyflow.utils.Constants; +import com.skyflow.utils.Utils; +import com.skyflow.vault.data.FileUploadRequest; import com.skyflow.vault.data.InsertRequest; import com.skyflow.vault.data.UpdateRequest; -import com.skyflow.vault.detect.*; import com.skyflow.vault.detect.DeidentifyFileRequest; import com.skyflow.vault.detect.DeidentifyTextRequest; +import com.skyflow.vault.detect.*; import com.skyflow.vault.tokens.ColumnValue; import com.skyflow.vault.tokens.DetokenizeData; import com.skyflow.vault.tokens.DetokenizeRequest; @@ -293,6 +297,97 @@ public void testGetTokenizePayload() { } } + @Test + public void testGetUploadFileColumnNameWithInvalidBase64String() { + try { + String invalidbase64String = "invalidBase64String!"; + String columnName = "columnName"; + String skyflowId = "skyflowId"; + String fileName = "fileName.txt"; + FileUploadRequest request = FileUploadRequest.builder() + .tableName(table) + .columnName(columnName) + .skyflowId(skyflowId) + .base64(invalidbase64String) + .fileName(fileName) + .build(); + vaultClient.getUploadFileColumnName(request); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.InvalidBase64InFileUpload.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } catch (Exception e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testGetUploadFileColumnNameWithValidBase64String() { + try { + String invalidbase64String = "YmFzZTY0RW5jb2RlZFN0cmluZw=="; + String columnName = "columnName"; + String skyflowId = "skyflowId"; + String fileName = "fileName.txt"; + FileUploadRequest request = FileUploadRequest.builder() + .tableName(table) + .columnName(columnName) + .skyflowId(skyflowId) + .base64(invalidbase64String) + .fileName(fileName) + .build(); + vaultClient.getUploadFileColumnName(request); + } catch (Exception e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testGetUploadFileColumnNameWithInvalidFilePath() { + try { + String invalidFilePath = "invalid/file/path/file.txt"; + String columnName = "columnName"; + String skyflowId = "skyflowId"; + FileUploadRequest request = FileUploadRequest.builder() + .tableName(table) + .columnName(columnName) + .skyflowId(skyflowId) + .filePath(invalidFilePath) + .build(); + vaultClient.getUploadFileColumnName(request); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.InvalidFilePath.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } catch (Exception e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testGetUploadFileColumnNameWithValidFile() { + try { + String columnName = "columnName"; + String skyflowId = "skyflowId"; + String filePath = "src/test/resources/notJson.txt"; + FileUploadRequest request = FileUploadRequest.builder() + .tableName(table) + .columnName(columnName) + .skyflowId(skyflowId) + .fileObject(new File(filePath)) + .build(); + vaultClient.getUploadFileColumnName(request); + Assert.assertTrue(request.getFileObject().exists()); + Assert.assertEquals("notJson.txt", request.getFileObject().getName()); + } catch (Exception e) { + System.out.println(e); + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + @Test public void testSetBearerToken() { try { diff --git a/src/test/java/com/skyflow/vault/controller/VaultControllerTests.java b/src/test/java/com/skyflow/vault/controller/VaultControllerTests.java index 5f3ae771..addf4d08 100644 --- a/src/test/java/com/skyflow/vault/controller/VaultControllerTests.java +++ b/src/test/java/com/skyflow/vault/controller/VaultControllerTests.java @@ -165,4 +165,24 @@ public void testInvalidRequestInTokenizeMethod() { } } + @Test + public void testInvalidRequestInUploadFileMethod() { + try { + FileUploadRequest request = FileUploadRequest.builder().build(); + skyflowClient = Skyflow.builder().setLogLevel(LogLevel.DEBUG).addVaultConfig(vaultConfig).build(); + skyflowClient.vault().uploadFile(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.TableNameKeyError.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + Assert.assertNull(e.getRequestId()); + Assert.assertNull(e.getGrpcCode()); + Assert.assertTrue(e.getDetails().isEmpty()); + Assert.assertEquals(HttpStatus.BAD_REQUEST.getHttpStatus(), e.getHttpStatus()); + } + } + } diff --git a/src/test/java/com/skyflow/vault/data/FileUploadTests.java b/src/test/java/com/skyflow/vault/data/FileUploadTests.java new file mode 100644 index 00000000..fdade9c1 --- /dev/null +++ b/src/test/java/com/skyflow/vault/data/FileUploadTests.java @@ -0,0 +1,359 @@ +package com.skyflow.vault.data; + +import com.skyflow.config.Credentials; +import com.skyflow.config.VaultConfig; +import com.skyflow.enums.Env; +import com.skyflow.errors.ErrorCode; +import com.skyflow.errors.ErrorMessage; +import com.skyflow.errors.SkyflowException; +import com.skyflow.utils.Constants; +import com.skyflow.utils.Utils; +import com.skyflow.utils.validations.Validations; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; + +public class FileUploadTests { + private static final String INVALID_EXCEPTION_THROWN = "Should not have thrown any exception"; + private static final String EXCEPTION_NOT_THROWN = "Should have thrown an exception"; + private static String vaultID = null; + private static String clusterID = null; + private static String skyflowID = null; + private static String tableName = null; + private static String columnName = null; + private static String filePath = null; + private static String fileName = null; + private static File testFile = null; + private static String validbase64String = "YmFzZTY0RW5jb2RlZFN0cmluZw=="; + + @BeforeClass + public static void setup() { + vaultID = "vault123"; + clusterID = "cluster123"; + + Credentials credentials = new Credentials(); + credentials.setToken("valid-token"); + + VaultConfig vaultConfig = new VaultConfig(); + vaultConfig.setVaultId(vaultID); + vaultConfig.setClusterId(clusterID); + vaultConfig.setEnv(Env.DEV); + skyflowID = "test_file_upload_id_1"; + tableName = "test_table"; + columnName = "profile_image"; + fileName = "notJson.txt"; + filePath = "src/test/resources/" + fileName; + testFile = new File(filePath); + } + + @Test + public void testValidFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .fileObject(testFile) + .tableName(tableName) + .columnName(columnName) + .skyflowId(skyflowID) + .fileName(fileName) + .build(); + Validations.validateFileUploadRequest(request); + Assert.assertEquals(tableName, request.getTableName()); + Assert.assertEquals(columnName, request.getColumnName()); + Assert.assertEquals(testFile, request.getFileObject()); + Assert.assertEquals(fileName, request.getFileName()); + } catch (SkyflowException e) { + Assert.fail(INVALID_EXCEPTION_THROWN + " " + e); + } + } + + @Test + public void testNullRequestInFileUploadRequestValidations() { + try { + Validations.validateFileUploadRequest(null); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.InvalidFileUploadRequest.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testNoTableInFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .fileObject(testFile) + .columnName(columnName) + .fileName(fileName) + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.TableNameKeyError.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testEmptyTableInFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .fileObject(testFile) + .tableName("") + .columnName(columnName) + .fileName(fileName) + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.EmptyTableName.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testNoColumnInFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .fileObject(testFile) + .tableName(tableName) + .skyflowId(skyflowID) + .fileName(fileName) + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.ColumnNameKeyErrorInFileUpload.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testEmptyColumnInFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .fileObject(testFile) + .tableName(tableName) + .columnName("") + .skyflowId(skyflowID) + .fileName(fileName) + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.EmptyColumnNameInFileUpload.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testNoSkyflowIdInFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .fileObject(testFile) + .tableName(tableName) + .columnName(columnName) + .fileName(fileName) + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.SkyflowIdKeyErrorInFileUpload.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testEmptySkyflowIdInFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .fileObject(testFile) + .tableName(tableName) + .columnName(columnName) + .fileName(fileName) + .skyflowId("") + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.EmptySkyflowIdInFileUpload.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testNoFileInUploadRequestValidations() { + FileUploadRequest request = FileUploadRequest.builder() + .tableName(tableName) + .columnName(columnName) + .skyflowId(skyflowID) + .fileName(fileName) + .build(); + try { + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.MissingFileSourceInFileUpload.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testMultipleFileSourcesInFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .fileObject(testFile) + .filePath(filePath) + .tableName(tableName) + .columnName(columnName) + .fileName(fileName) + .skyflowId(skyflowID) + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.MultipleFileSourcesInFileUpload.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testNoFileNameForBase64InFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .base64(validbase64String) + .tableName(tableName) + .columnName(columnName) + .skyflowId(skyflowID) + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.MissingFileNameForBase64.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testInvalidFileObjectInFileUploadRequestValidations() { + try { + File invalidFile = new File("nonexistent.txt"); + FileUploadRequest request = FileUploadRequest.builder() + .fileObject(invalidFile) + .tableName(tableName) + .columnName(columnName) + .fileName(fileName) + .skyflowId(skyflowID) + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.InvalidFileObjectInFileUpload.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testValidBase64InFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .base64(validbase64String) + .tableName(tableName) + .columnName(columnName) + .fileName(fileName) + .skyflowId(skyflowID) + .build(); + Validations.validateFileUploadRequest(request); + Assert.assertEquals(tableName, request.getTableName()); + Assert.assertEquals(columnName, request.getColumnName()); + Assert.assertEquals(fileName, request.getFileName()); + Assert.assertEquals(validbase64String, request.getBase64()); + } catch (SkyflowException e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testValidFilePathInFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .filePath(filePath) + .tableName(tableName) + .columnName(columnName) + .skyflowId(skyflowID) + .build(); + Validations.validateFileUploadRequest(request); + Assert.assertEquals(tableName, request.getTableName()); + Assert.assertEquals(columnName, request.getColumnName()); + Assert.assertEquals(filePath, request.getFilePath()); + } catch (SkyflowException e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } + + @Test + public void testEmptyFilePathInFileUploadRequestValidations() { + try { + FileUploadRequest request = FileUploadRequest.builder() + .filePath("") + .tableName(tableName) + .columnName(columnName) + .skyflowId(skyflowID) + .build(); + Validations.validateFileUploadRequest(request); + Assert.fail(EXCEPTION_NOT_THROWN); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals( + Utils.parameterizedString(ErrorMessage.EmptyFilePathInFileUpload.getMessage(), Constants.SDK_PREFIX), + e.getMessage() + ); + } + } + + @Test + public void testFileUploadResponse() { + try { + FileUploadResponse response = new FileUploadResponse(skyflowID); + String responseString = "{\"skyflowId\":\"" + skyflowID + "\",\"errors\":null}"; + Assert.assertEquals(skyflowID, response.getSkyflowId()); + Assert.assertEquals(responseString, response.toString()); + } catch (Exception e) { + Assert.fail(INVALID_EXCEPTION_THROWN); + } + } +}