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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/internal-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
uses: ./.github/workflows/shared-build-and-deploy.yml
with:
ref: ${{ github.ref_name }}
server-id: central
server-id: skyflow-jfrog
profile: jfrog
tag: 'internal'
module: ${{ needs.resolve-module.outputs.module }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.skyflow.detect.internal;

import com.skyflow.detect.ReidentifyFileRequest;
import com.skyflow.errors.ErrorMessage;
import com.skyflow.errors.BaseErrorMessage;
import com.skyflow.errors.ErrorCode;
import com.skyflow.errors.SkyflowException;
import com.skyflow.logs.ErrorLogs;
Expand All @@ -20,13 +20,13 @@ private ReidentifyFileValidations() {

public static void validateReidentifyFileRequest(ReidentifyFileRequest request) throws SkyflowException {
if (request == null) {
throw invalid(ErrorLogs.REIDENTIFY_FILE_REQUEST_NULL, ErrorMessage.ReidentifyFileRequestNull);
throw invalid(ErrorLogs.REIDENTIFY_FILE_REQUEST_NULL, BaseErrorMessage.ReidentifyFileRequestNull);
}
if (request.getDataSource() == null) {
throw invalid(ErrorLogs.INVALID_DATA_SOURCE_IN_REIDENTIFY_FILE, ErrorMessage.InvalidDataSourceInReidentifyFile);
throw invalid(ErrorLogs.INVALID_DATA_SOURCE_IN_REIDENTIFY_FILE, BaseErrorMessage.InvalidDataSourceInReidentifyFile);
}
if (isBlank(request.getValue())) {
throw invalid(ErrorLogs.INVALID_VALUE_IN_REIDENTIFY_FILE, ErrorMessage.InvalidValueInReidentifyFile);
throw invalid(ErrorLogs.INVALID_VALUE_IN_REIDENTIFY_FILE, BaseErrorMessage.InvalidValueInReidentifyFile);
}
// redactionLevel entries are optional on the API and are passed through as given.
}
Expand All @@ -36,7 +36,7 @@ private static boolean isBlank(String value) {
return value == null || value.trim().isEmpty();
}

private static SkyflowException invalid(ErrorLogs log, ErrorMessage message) {
private static SkyflowException invalid(ErrorLogs log, BaseErrorMessage message) {
LogUtil.printErrorLog(BaseUtils.parameterizedString(log.getLog(), INTERFACE_NAME));
return new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), message.getMessage());
}
Expand Down
3 changes: 3 additions & 0 deletions common/src/main/java/com/skyflow/errors/BaseErrorMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ public enum BaseErrorMessage {
OutputDirectoryWithoutPollOptions("%s0 Validation error. outputDirectory in deidentify file request requires pollOptions."),
FailedToWriteOutputFile("%s0 Failed to write the processed output to %s1."),
GetRunRequestNull("%s0 Validation error. GetRun request cannot be null."),
ReidentifyFileRequestNull("%s0 Validation error. ReidentifyFile request cannot be null."),
InvalidDataSourceInReidentifyFile("%s0 Validation error. Invalid dataSource in reidentify file request. Specify BASE64, SKYFLOW_ID or PRESIGNED_URL."),
InvalidValueInReidentifyFile("%s0 Validation error. Invalid value in reidentify file request. Specify the non-empty base64 content, skyflow id or presigned URL of the file."),
InvalidRunIdInGetRun("%s0 Validation error. Invalid runId in get run request. Specify a non-empty run id."),
CheckGuardrailsRequestNull("%s0 Validation error. CheckGuardrails request cannot be null."),
InvalidTextInCheckGuardrails("%s0 Validation error. Invalid text in check guardrails request. Specify a non-empty text."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@
import com.skyflow.config.BaseVaultConfig;
import com.skyflow.detect.CheckGuardrailsRequest;
import com.skyflow.detect.CheckGuardrailsResponse;
import com.skyflow.detect.DeidentifyFileRequest;
import com.skyflow.detect.DeidentifyFileResponse;
import com.skyflow.detect.DeidentifyStringRequest;
import com.skyflow.detect.DeidentifyStringResponse;
import com.skyflow.detect.GetRunRequest;
import com.skyflow.detect.GetRunResponse;
import com.skyflow.detect.ReidentifyFileRequest;
import com.skyflow.detect.ReidentifyFileResponse;
import com.skyflow.detect.ReidentifyStringRequest;
import com.skyflow.detect.ReidentifyStringResponse;
import com.skyflow.detect.internal.DeidentifyFileFlow;
import com.skyflow.detect.internal.DetectRequestMapper;
import com.skyflow.detect.internal.DetectResponseMapper;
import com.skyflow.detect.internal.DetectValidations;
import com.skyflow.detect.internal.ReidentifyFileMapper;
import com.skyflow.detect.internal.ReidentifyFileValidations;
import com.skyflow.errors.SkyflowException;
import com.skyflow.generated.detect.rest.core.ApiClientApiException;
import com.skyflow.generated.detect.rest.core.ApiClientException;
Expand All @@ -22,15 +29,19 @@
import com.skyflow.generated.detect.rest.core.ObjectMappers;
import com.skyflow.generated.detect.rest.core.RequestOptions;
import com.skyflow.generated.detect.rest.resources.filesv2.FilesV2Client;
import com.skyflow.generated.detect.rest.resources.filesv2.requests.DeidentifyFileRequestV2;
import com.skyflow.generated.detect.rest.resources.filesv2.requests.GetRunV2Request;
import com.skyflow.generated.detect.rest.resources.filesv2.requests.ReidentifyFileRequestV2;
import com.skyflow.generated.detect.rest.resources.guardrailsv2.GuardrailsV2Client;
import com.skyflow.generated.detect.rest.resources.guardrailsv2.requests.DetectGuardrailsRequestV2;
import com.skyflow.generated.detect.rest.resources.stringsv2.StringsV2Client;
import com.skyflow.generated.detect.rest.resources.stringsv2.requests.DeidentifyStringRequestV2;
import com.skyflow.generated.detect.rest.resources.stringsv2.requests.ReidentifyStringRequestV2;
import com.skyflow.generated.detect.rest.types.DeidentifyFileResponseV2;
import com.skyflow.generated.detect.rest.types.DeidentifyStringResponseV2;
import com.skyflow.generated.detect.rest.types.DetectGuardrailsResponseV2;
import com.skyflow.generated.detect.rest.types.DetectRunsResponseV2;
import com.skyflow.generated.detect.rest.types.ReidentifyFileResponseV2;
import com.skyflow.generated.detect.rest.types.ReidentifyStringResponseV2;
import com.skyflow.logs.ErrorLogs;
import com.skyflow.logs.InfoLogs;
Expand Down Expand Up @@ -222,6 +233,68 @@ public ReidentifyStringResponse reidentifyString(ReidentifyStringRequest request
}
}

/**
* Detects and de-identifies sensitive data in a file. The API is asynchronous: by default this
* submits the run and returns its id for use with {@link #getRun}. With
* {@link DeidentifyFileRequest#getPollOptions() pollOptions} the SDK polls the run with exponential
* backoff and returns the completed run, or the run id with a non-terminal status if the budget
* runs out. On success, a request built from a local file has its outputs written to disk.
*
* @param request the file (base64, skyflow id, presigned URL, or a local file) plus a stored or inline configuration
* @return run id, and the run's status, outputs and metrics when polled
* @throws SkyflowException on validation failure, credential failure, an API error or an output write failure
*/
public DeidentifyFileResponse deidentifyFile(DeidentifyFileRequest request) throws SkyflowException {
LogUtil.printInfoLog(InfoLogs.DEIDENTIFY_FILE_TRIGGERED.getLog());
LogUtil.printInfoLog(InfoLogs.VALIDATE_DEIDENTIFY_FILE_REQUEST.getLog());
DetectValidations.validateDeidentifyFileRequest(request);
String token = resolveToken();
DeidentifyFileRequestV2 apiRequest = DetectRequestMapper.toDeidentifyFileRequest(request, this.vaultConfig.getVaultId());
String runId;
try {
DeidentifyFileResponseV2 apiResponse = filesClient().deidentifyFileV2(apiRequest, requestOptions(token));
LogUtil.printInfoLog(InfoLogs.DEIDENTIFY_FILE_REQUEST_RESOLVED.getLog());
runId = apiResponse.getRunId().orElse(null);
} catch (ApiClientApiException e) {
throw toSkyflowException(e, ErrorLogs.DEIDENTIFY_FILE_REQUEST_REJECTED);
} catch (ApiClientException e) {
LogUtil.printErrorLog(ErrorLogs.DEIDENTIFY_FILE_REQUEST_REJECTED.getLog());
throw new SkyflowException(e);
}
DeidentifyFileResponse response = DeidentifyFileFlow.complete(request, runId,
id -> getRun(GetRunRequest.builder().runId(id).build()));
LogUtil.printInfoLog(InfoLogs.DEIDENTIFY_FILE_SUCCESS.getLog());
return response;
}

/**
* Replaces tokens in a file with their original values or a redacted rendering. Synchronous:
* the re-identified file is returned in the response rather than through a run id.
*
* @param request the file (base64, skyflow id or presigned URL) plus optional per-group redaction rules
* @return status, output files and metrics
* @throws SkyflowException on validation failure, credential failure or an API error
*/
public ReidentifyFileResponse reidentifyFile(ReidentifyFileRequest request) throws SkyflowException {
LogUtil.printInfoLog(InfoLogs.REIDENTIFY_FILE_TRIGGERED.getLog());
LogUtil.printInfoLog(InfoLogs.VALIDATE_REIDENTIFY_FILE_REQUEST.getLog());
ReidentifyFileValidations.validateReidentifyFileRequest(request);
String token = resolveToken();
ReidentifyFileRequestV2 apiRequest = ReidentifyFileMapper.toApiRequest(request, this.vaultConfig.getVaultId());
try {
ReidentifyFileResponseV2 apiResponse = filesClient().reidentifyFileV2(apiRequest, requestOptions(token));
LogUtil.printInfoLog(InfoLogs.REIDENTIFY_FILE_REQUEST_RESOLVED.getLog());
ReidentifyFileResponse response = ReidentifyFileMapper.toResponse(apiResponse);
LogUtil.printInfoLog(InfoLogs.REIDENTIFY_FILE_SUCCESS.getLog());
return response;
} catch (ApiClientApiException e) {
throw toSkyflowException(e, ErrorLogs.REIDENTIFY_FILE_REQUEST_REJECTED);
} catch (ApiClientException e) {
LogUtil.printErrorLog(ErrorLogs.REIDENTIFY_FILE_REQUEST_REJECTED.getLog());
throw new SkyflowException(e);
}
}

/**
* Retrieves the status and, once complete, the outputs of a Detect file run.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import com.skyflow.detect.RedactionType;
import com.skyflow.detect.ReidentifyFileRequest;
import com.skyflow.errors.ErrorCode;
import com.skyflow.errors.ErrorMessage;
import com.skyflow.errors.BaseErrorMessage;
import com.skyflow.errors.SkyflowException;
import org.junit.Assert;
import org.junit.Test;
Expand All @@ -20,7 +20,7 @@ private static ReidentifyFileRequest.ReidentifyFileRequestBuilder valid() {
return ReidentifyFileRequest.builder().dataSource(DataSourceType.BASE64).value("Zm9v");
}

private static void assertRejected(ReidentifyFileRequest request, ErrorMessage expected) {
private static void assertRejected(ReidentifyFileRequest request, BaseErrorMessage expected) {
try {
ReidentifyFileValidations.validateReidentifyFileRequest(request);
Assert.fail("expected SkyflowException: " + expected);
Expand All @@ -32,25 +32,25 @@ private static void assertRejected(ReidentifyFileRequest request, ErrorMessage e

@Test
public void rejectsNullRequest() {
assertRejected(null, ErrorMessage.ReidentifyFileRequestNull);
assertRejected(null, BaseErrorMessage.ReidentifyFileRequestNull);
}

@Test
public void rejectsMissingDataSource() {
assertRejected(ReidentifyFileRequest.builder().value("Zm9v").build(), ErrorMessage.InvalidDataSourceInReidentifyFile);
assertRejected(ReidentifyFileRequest.builder().value("Zm9v").build(), BaseErrorMessage.InvalidDataSourceInReidentifyFile);
}

@Test
public void rejectsNullOrBlankValue() {
assertRejected(ReidentifyFileRequest.builder().dataSource(DataSourceType.BASE64).build(), ErrorMessage.InvalidValueInReidentifyFile);
assertRejected(valid().value("").build(), ErrorMessage.InvalidValueInReidentifyFile);
assertRejected(valid().value(" \t").build(), ErrorMessage.InvalidValueInReidentifyFile);
assertRejected(ReidentifyFileRequest.builder().dataSource(DataSourceType.BASE64).build(), BaseErrorMessage.InvalidValueInReidentifyFile);
assertRejected(valid().value("").build(), BaseErrorMessage.InvalidValueInReidentifyFile);
assertRejected(valid().value(" \t").build(), BaseErrorMessage.InvalidValueInReidentifyFile);
}

@Test
public void checksFieldsInOrderDataSourceBeforeValue() {
// Both missing: dataSource is reported first.
assertRejected(ReidentifyFileRequest.builder().build(), ErrorMessage.InvalidDataSourceInReidentifyFile);
assertRejected(ReidentifyFileRequest.builder().build(), BaseErrorMessage.InvalidDataSourceInReidentifyFile);
}

@Test
Expand Down
Loading
Loading