feat: Added Smart substitution support for S3 (#9124)
* Test case * Dummy commit for tests to pass * Removed logic for double escapes * Renamed from BSON to JSON
This commit is contained in:
parent
7a2bd98ca0
commit
93de065fa8
|
|
@ -245,7 +245,6 @@ public class DataTypeStringUtils {
|
|||
case STRING:
|
||||
default:
|
||||
try {
|
||||
replacement = escapeSpecialCharacters(replacement);
|
||||
String valueAsString = objectMapper.writeValueAsString(replacement);
|
||||
input = placeholderPattern.matcher(input).replaceFirst(Matcher.quoteReplacement(valueAsString));
|
||||
} catch (JsonProcessingException e) {
|
||||
|
|
@ -262,19 +261,6 @@ public class DataTypeStringUtils {
|
|||
return input;
|
||||
}
|
||||
|
||||
private static String escapeSpecialCharacters(String raw) {
|
||||
String escaped = raw;
|
||||
escaped = escaped.replace("\\", "\\\\");
|
||||
escaped = escaped.replace("\"", "\\\"");
|
||||
escaped = escaped.replace("\b", "\\b");
|
||||
escaped = escaped.replace("\f", "\\f");
|
||||
escaped = escaped.replace("\n", "\\n");
|
||||
escaped = escaped.replace("\r", "\\r");
|
||||
escaped = escaped.replace("\t", "\\t");
|
||||
// TODO: escape other non-printing characters using uXXXX notation
|
||||
return escaped;
|
||||
}
|
||||
|
||||
private static boolean isBinary(String input) {
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
int tempB = input.charAt(i);
|
||||
|
|
|
|||
|
|
@ -13,10 +13,13 @@ import com.amazonaws.services.s3.model.S3ObjectSummary;
|
|||
import com.amazonaws.services.s3.transfer.TransferManager;
|
||||
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
|
||||
import com.amazonaws.util.IOUtils;
|
||||
import com.appsmith.external.dtos.ExecuteActionDTO;
|
||||
import com.appsmith.external.dtos.MultipartFormDataDTO;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.StaleConnectionException;
|
||||
import com.appsmith.external.helpers.DataTypeStringUtils;
|
||||
import com.appsmith.external.helpers.MustacheHelper;
|
||||
import com.appsmith.external.models.ActionConfiguration;
|
||||
import com.appsmith.external.models.ActionExecutionRequest;
|
||||
import com.appsmith.external.models.ActionExecutionResult;
|
||||
|
|
@ -28,6 +31,7 @@ import com.appsmith.external.models.Property;
|
|||
import com.appsmith.external.models.RequestParamDTO;
|
||||
import com.appsmith.external.plugins.BasePlugin;
|
||||
import com.appsmith.external.plugins.PluginExecutor;
|
||||
import com.appsmith.external.plugins.SmartSubstitutionInterface;
|
||||
import com.external.plugins.constants.AmazonS3Action;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.pf4j.Extension;
|
||||
|
|
@ -72,12 +76,14 @@ import static com.external.plugins.constants.FieldName.LIST_UNSIGNED_URL;
|
|||
import static com.external.plugins.constants.FieldName.PATH;
|
||||
import static com.external.plugins.constants.FieldName.READ_USING_BASE64_ENCODING;
|
||||
import static com.external.utils.DatasourceUtils.getS3ClientBuilder;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
public class AmazonS3Plugin extends BasePlugin {
|
||||
|
||||
private static final String S3_DRIVER = "com.amazonaws.services.s3.AmazonS3";
|
||||
public static final int S3_SERVICE_PROVIDER_PROPERTY_INDEX = 1;
|
||||
public static final int CUSTOM_ENDPOINT_REGION_PROPERTY_INDEX = 2;
|
||||
public static final String SMART_SUBSTITUTION = "smartSubstitution";
|
||||
public static final int CUSTOM_ENDPOINT_INDEX = 0;
|
||||
private static final String DEFAULT_URL_EXPIRY_IN_MINUTES = "5"; // max 7 days is possible
|
||||
private static final String YES = "YES";
|
||||
|
|
@ -92,7 +98,7 @@ public class AmazonS3Plugin extends BasePlugin {
|
|||
|
||||
@Slf4j
|
||||
@Extension
|
||||
public static class S3PluginExecutor implements PluginExecutor<AmazonS3> {
|
||||
public static class S3PluginExecutor implements PluginExecutor<AmazonS3>, SmartSubstitutionInterface {
|
||||
private final Scheduler scheduler = Schedulers.elastic();
|
||||
|
||||
/*
|
||||
|
|
@ -283,9 +289,67 @@ public class AmazonS3Plugin extends BasePlugin {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<ActionExecutionResult> execute(AmazonS3 connection,
|
||||
DatasourceConfiguration datasourceConfiguration,
|
||||
ActionConfiguration actionConfiguration) {
|
||||
public Mono<ActionExecutionResult> execute(AmazonS3 connection, DatasourceConfiguration datasourceConfiguration, ActionConfiguration actionConfiguration) {
|
||||
// Unused function
|
||||
return Mono.error(new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, "Unsupported Operation"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<ActionExecutionResult> executeParameterized(AmazonS3 connection,
|
||||
ExecuteActionDTO executeActionDTO,
|
||||
DatasourceConfiguration datasourceConfiguration,
|
||||
ActionConfiguration actionConfiguration) {
|
||||
|
||||
|
||||
final Map<String, Object> formData = actionConfiguration.getFormData();
|
||||
List<Map.Entry<String, String>> parameters = new ArrayList<>();
|
||||
|
||||
Boolean smartJsonSubstitution = TRUE;
|
||||
|
||||
Object smartSubstitutionObject = formData.getOrDefault(SMART_SUBSTITUTION, TRUE);
|
||||
|
||||
if (smartSubstitutionObject instanceof Boolean) {
|
||||
smartJsonSubstitution = (Boolean) smartSubstitutionObject;
|
||||
} else if (smartSubstitutionObject instanceof String) {
|
||||
// Older UI configuration used to set this value as a string which may/may not be castable to a boolean
|
||||
// directly. This is to ensure we are backward compatible
|
||||
smartJsonSubstitution = Boolean.parseBoolean((String) smartSubstitutionObject);
|
||||
}
|
||||
|
||||
try {
|
||||
// Smartly substitute in Json fields and replace all the bindings with values.
|
||||
if (TRUE.equals(smartJsonSubstitution)) {
|
||||
final String body = actionConfiguration.getBody() != null ? actionConfiguration.getBody() : "";
|
||||
// First extract all the bindings in order
|
||||
List<String> mustacheKeysInOrder = MustacheHelper.extractMustacheKeysInOrder(body);
|
||||
// Replace all the bindings with a placeholder
|
||||
String updatedValue = MustacheHelper.replaceMustacheWithPlaceholder(body, mustacheKeysInOrder);
|
||||
|
||||
updatedValue = (String) smartSubstitutionOfBindings(updatedValue,
|
||||
mustacheKeysInOrder,
|
||||
executeActionDTO.getParams(),
|
||||
parameters);
|
||||
|
||||
actionConfiguration.setBody(updatedValue);
|
||||
|
||||
}
|
||||
} catch (AppsmithPluginException e) {
|
||||
// Initializing object for error condition
|
||||
ActionExecutionResult errorResult = new ActionExecutionResult();
|
||||
errorResult.setStatusCode(AppsmithPluginError.PLUGIN_ERROR.getAppErrorCode().toString());
|
||||
errorResult.setIsExecutionSuccess(false);
|
||||
errorResult.setErrorInfo(e);
|
||||
return Mono.just(errorResult);
|
||||
}
|
||||
|
||||
prepareConfigurationsForExecution(executeActionDTO, actionConfiguration, datasourceConfiguration);
|
||||
|
||||
return this.executeCommon(connection, datasourceConfiguration, actionConfiguration);
|
||||
}
|
||||
|
||||
private Mono<ActionExecutionResult> executeCommon(AmazonS3 connection,
|
||||
DatasourceConfiguration datasourceConfiguration,
|
||||
ActionConfiguration actionConfiguration) {
|
||||
|
||||
final String[] query = new String[1];
|
||||
Map<String, Object> requestProperties = new HashMap<>();
|
||||
|
|
@ -293,48 +357,48 @@ public class AmazonS3Plugin extends BasePlugin {
|
|||
|
||||
return Mono.fromCallable(() -> {
|
||||
|
||||
/*
|
||||
* - AmazonS3 API collection does not seem to provide any API to test connection validity or staleness.
|
||||
* Hence, unable to do stale connection check explicitly.
|
||||
* - If connection object is null, then assume stale connection.
|
||||
*/
|
||||
if (connection == null) {
|
||||
return Mono.error(new StaleConnectionException());
|
||||
}
|
||||
/*
|
||||
* - AmazonS3 API collection does not seem to provide any API to test connection validity or staleness.
|
||||
* Hence, unable to do stale connection check explicitly.
|
||||
* - If connection object is null, then assume stale connection.
|
||||
*/
|
||||
if (connection == null) {
|
||||
return Mono.error(new StaleConnectionException());
|
||||
}
|
||||
|
||||
if (actionConfiguration == null) {
|
||||
return Mono.error(
|
||||
new AppsmithPluginException(
|
||||
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
|
||||
"At least one of the mandatory fields in S3 query creation form is empty - 'Action'/" +
|
||||
"'Bucket Name'/'File Path'/'Content'. Please fill all the mandatory fields and try " +
|
||||
"again."
|
||||
)
|
||||
);
|
||||
}
|
||||
if (actionConfiguration == null) {
|
||||
return Mono.error(
|
||||
new AppsmithPluginException(
|
||||
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
|
||||
"At least one of the mandatory fields in S3 query creation form is empty - 'Action'/" +
|
||||
"'Bucket Name'/'File Path'/'Content'. Please fill all the mandatory fields and try " +
|
||||
"again."
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, Object> formData = actionConfiguration.getFormData();
|
||||
Map<String, Object> formData = actionConfiguration.getFormData();
|
||||
|
||||
String command = (String) getValueSafelyFromFormData(formData, COMMAND);
|
||||
String command = (String) getValueSafelyFromFormData(formData, COMMAND);
|
||||
|
||||
if (StringUtils.isNullOrEmpty(command)) {
|
||||
return Mono.error(
|
||||
new AppsmithPluginException(
|
||||
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
|
||||
"Mandatory parameter 'Command' is missing. Did you forget to select one of the commands" +
|
||||
" from the Command dropdown ?"
|
||||
)
|
||||
);
|
||||
}
|
||||
if (StringUtils.isNullOrEmpty(command)) {
|
||||
return Mono.error(
|
||||
new AppsmithPluginException(
|
||||
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
|
||||
"Mandatory parameter 'Command' is missing. Did you forget to select one of the commands" +
|
||||
" from the Command dropdown ?"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
AmazonS3Action s3Action = AmazonS3Action.valueOf(command);
|
||||
query[0] = s3Action.name();
|
||||
AmazonS3Action s3Action = AmazonS3Action.valueOf(command);
|
||||
query[0] = s3Action.name();
|
||||
|
||||
requestParams.add(new RequestParamDTO(COMMAND,
|
||||
command, null, null, null));
|
||||
requestParams.add(new RequestParamDTO(COMMAND,
|
||||
command, null, null, null));
|
||||
|
||||
final String bucketName = (s3Action == AmazonS3Action.LIST_BUCKETS) ?
|
||||
null : (String) getValueSafelyFromFormData(formData, BUCKET);
|
||||
final String bucketName = (s3Action == AmazonS3Action.LIST_BUCKETS) ?
|
||||
null : (String) getValueSafelyFromFormData(formData, BUCKET);
|
||||
|
||||
// If the action_type is LIST_BUCKET, remove the bucket name requirement
|
||||
if (s3Action != AmazonS3Action.LIST_BUCKETS
|
||||
|
|
@ -762,7 +826,19 @@ public class AmazonS3Plugin extends BasePlugin {
|
|||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
actionConfiguration.setFormData(configMap);
|
||||
return datasourceCreate(datasourceConfiguration)
|
||||
.flatMap(connection -> execute(connection, datasourceConfiguration, actionConfiguration));
|
||||
.flatMap(connection -> executeParameterized(connection, new ExecuteActionDTO(), datasourceConfiguration, actionConfiguration));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object substituteValueInInput(int index,
|
||||
String binding,
|
||||
String value,
|
||||
Object input,
|
||||
List<Map.Entry<String, String>> insertedParams,
|
||||
Object... args) {
|
||||
String jsonBody = (String) input;
|
||||
return DataTypeStringUtils.jsonSmartReplacementPlaceholderWithValue(jsonBody, value, insertedParams);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"setting": [
|
||||
{
|
||||
"sectionName": "",
|
||||
"id": 1,
|
||||
"children": [
|
||||
{
|
||||
"label": "Run query on page load",
|
||||
"configProperty": "executeOnLoad",
|
||||
"controlType": "SWITCH",
|
||||
"info": "Will refresh data each time the page is loaded"
|
||||
},
|
||||
{
|
||||
"label": "Request confirmation before running query",
|
||||
"configProperty": "confirmBeforeExecute",
|
||||
"controlType": "SWITCH",
|
||||
"info": "Ask confirmation from the user each time before refreshing data"
|
||||
},
|
||||
{
|
||||
"label": "Smart JSON Substitution",
|
||||
"info": "Turning on this property fixes the JSON substitution of bindings in the Content field by adding/removing quotes intelligently and reduces developer errors",
|
||||
"configProperty": "actionConfiguration.formData.smartSubstitution",
|
||||
"controlType": "SWITCH",
|
||||
"initialValue": true
|
||||
},
|
||||
{
|
||||
"label": "Query timeout (in milliseconds)",
|
||||
"info": "Maximum time after which the query will return",
|
||||
"configProperty": "actionConfiguration.timeoutInMillisecond",
|
||||
"controlType": "INPUT_TEXT",
|
||||
"dataType": "NUMBER"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import com.amazonaws.services.s3.model.S3Object;
|
|||
import com.amazonaws.services.s3.model.S3ObjectInputStream;
|
||||
import com.amazonaws.services.s3.model.S3ObjectSummary;
|
||||
import com.amazonaws.util.Base64;
|
||||
import com.appsmith.external.dtos.ExecuteActionDTO;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.StaleConnectionException;
|
||||
import com.appsmith.external.models.ActionConfiguration;
|
||||
|
|
@ -15,6 +16,7 @@ import com.appsmith.external.models.ActionExecutionResult;
|
|||
import com.appsmith.external.models.DBAuth;
|
||||
import com.appsmith.external.models.DatasourceConfiguration;
|
||||
import com.appsmith.external.models.Endpoint;
|
||||
import com.appsmith.external.models.Param;
|
||||
import com.appsmith.external.models.Property;
|
||||
import com.appsmith.external.models.RequestParamDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -36,6 +38,7 @@ import java.util.Set;
|
|||
|
||||
import static com.appsmith.external.constants.ActionConstants.ACTION_CONFIGURATION_PATH;
|
||||
import static com.appsmith.external.helpers.PluginUtils.setValueSafelyInFormData;
|
||||
import static com.external.plugins.AmazonS3Plugin.SMART_SUBSTITUTION;
|
||||
import static com.external.plugins.constants.FieldName.BUCKET;
|
||||
import static com.external.plugins.constants.FieldName.COMMAND;
|
||||
import static com.external.plugins.constants.FieldName.CREATE_DATATYPE;
|
||||
|
|
@ -216,12 +219,15 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testStaleConnectionExceptionFromExecuteMethod() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
actionConfiguration.setFormData(Map.of());
|
||||
Mono<AmazonS3Plugin.S3PluginExecutor> pluginExecutorMono = Mono.just(new AmazonS3Plugin.S3PluginExecutor());
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutorMono
|
||||
.flatMap(executor -> {
|
||||
return executor.execute(
|
||||
return executor.executeParameterized(
|
||||
null,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
});
|
||||
|
|
@ -233,6 +239,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testListFilesInBucketWithNoUrl() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -266,10 +273,11 @@ public class AmazonS3PluginTest {
|
|||
when(mockConnection.listNextBatchOfObjects(mockObjectListing)).thenReturn(mockObjectListing);
|
||||
when(mockObjectListing.getObjectSummaries()).thenReturn(mockS3ObjectSummaryList);
|
||||
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
mockConnection,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
mockConnection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(result -> {
|
||||
|
|
@ -293,12 +301,13 @@ public class AmazonS3PluginTest {
|
|||
/*
|
||||
* - This method tests the create file program flow till the point where an actual call is made by the AmazonS3
|
||||
* connection to upload a file.
|
||||
* - If everything goes well, then then only expected exception is the one thrown by AmazonS3 connection
|
||||
* - If everything goes well, then only expected exception is the one thrown by AmazonS3 connection
|
||||
* regarding false credentials.
|
||||
*/
|
||||
@Test
|
||||
public void testCreateFileFromBodyWithFalseCredentialsAndNonNullDuration() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -317,10 +326,11 @@ public class AmazonS3PluginTest {
|
|||
actionConfiguration.setFormData(configMap);
|
||||
|
||||
AmazonS3 connection = pluginExecutor.datasourceCreate(datasourceConfiguration).block();
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
connection,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
connection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(result -> {
|
||||
|
|
@ -336,12 +346,13 @@ public class AmazonS3PluginTest {
|
|||
/*
|
||||
* - This method tests the create file program flow till the point where an actual call is made by the AmazonS3
|
||||
* connection to upload a file.
|
||||
* - If everything goes well, then then only expected exception is the one thrown by AmazonS3 connection
|
||||
* - If everything goes well, then only expected exception is the one thrown by AmazonS3 connection
|
||||
* regarding false credentials.
|
||||
*/
|
||||
@Test
|
||||
public void testFileUploadFromBodyWithMissingDuration() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -359,8 +370,56 @@ public class AmazonS3PluginTest {
|
|||
actionConfiguration.setFormData(configMap);
|
||||
|
||||
AmazonS3 connection = pluginExecutor.datasourceCreate(datasourceConfiguration).block();
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
connection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(result -> {
|
||||
assertFalse(result.getIsExecutionSuccess());
|
||||
String message = (String) result.getBody();
|
||||
assertTrue(message.contains("The AWS Access Key Id you provided does not exist in " +
|
||||
"our records"));
|
||||
assertEquals(AppsmithPluginError.PLUGIN_ERROR.getTitle(), result.getTitle());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
/*
|
||||
* - This method tests the create file program flow till the point where an actual call is made by the AmazonS3
|
||||
* connection to upload a file.
|
||||
* - If this test fails, the point of failure is expected to be the logic for smart substitution
|
||||
* - If everything goes well, then only expected exception is the one thrown by AmazonS3 connection
|
||||
* regarding false credentials.
|
||||
*/
|
||||
@Test
|
||||
public void testSmartSubstitutionJSONBody() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
executeActionDTO.setParams(List.of(new Param("dynamicallyFoundFilePickerObject", "<html>Random\"Unescaped'String</html>")));
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
String dummyBody = "{\"data\": {{dynamicallyFoundFilePickerObject}}}";
|
||||
actionConfiguration.setBody(dummyBody);
|
||||
|
||||
String dummyPath = "path";
|
||||
actionConfiguration.setPath(dummyPath);
|
||||
|
||||
Map<String, Object> configMap = new HashMap<>();
|
||||
setValueSafelyInFormData(configMap, SMART_SUBSTITUTION, true);
|
||||
setValueSafelyInFormData(configMap, COMMAND, "UPLOAD_FILE_FROM_BODY");
|
||||
setValueSafelyInFormData(configMap, BUCKET, "bucket_name");
|
||||
setValueSafelyInFormData(configMap, CREATE_DATATYPE, "NO");
|
||||
|
||||
actionConfiguration.setFormData(configMap);
|
||||
|
||||
AmazonS3 connection = pluginExecutor.datasourceCreate(datasourceConfiguration).block();
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
connection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
|
|
@ -378,6 +437,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testFileUploadFromBody_withMalformedBody_returnsErrorMessage() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -396,8 +456,9 @@ public class AmazonS3PluginTest {
|
|||
actionConfiguration.setFormData(configMap);
|
||||
|
||||
AmazonS3 connection = pluginExecutor.datasourceCreate(datasourceConfiguration).block();
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
connection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
|
|
@ -428,6 +489,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testFileUploadFromBodyWithFilepickerAndNonBase64() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -446,10 +508,11 @@ public class AmazonS3PluginTest {
|
|||
actionConfiguration.setFormData(configMap);
|
||||
|
||||
AmazonS3 connection = pluginExecutor.datasourceCreate(datasourceConfiguration).block();
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
connection,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
connection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(result -> {
|
||||
|
|
@ -478,6 +541,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testReadFileFromPathWithoutBase64Encoding() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -503,10 +567,11 @@ public class AmazonS3PluginTest {
|
|||
S3ObjectInputStream dummyS3ObjectInputStream = new S3ObjectInputStream(dummyInputStream, null);
|
||||
when(mockS3Object.getObjectContent()).thenReturn(dummyS3ObjectInputStream);
|
||||
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
mockConnection,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
mockConnection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(result -> {
|
||||
|
|
@ -520,6 +585,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testReadFileFromPathWithBase64Encoding() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -545,8 +611,9 @@ public class AmazonS3PluginTest {
|
|||
S3ObjectInputStream dummyS3ObjectInputStream = new S3ObjectInputStream(dummyInputStream, null);
|
||||
when(mockS3Object.getObjectContent()).thenReturn(dummyS3ObjectInputStream);
|
||||
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
mockConnection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
|
|
@ -576,6 +643,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testDeleteFile() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -594,10 +662,11 @@ public class AmazonS3PluginTest {
|
|||
AmazonS3 mockConnection = mock(AmazonS3.class);
|
||||
doNothing().when(mockConnection).deleteObject(anyString(), anyString());
|
||||
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
mockConnection,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
mockConnection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(result -> {
|
||||
assertTrue(result.getIsExecutionSuccess());
|
||||
|
|
@ -624,6 +693,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testListFilesWithPrefix() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -657,8 +727,9 @@ public class AmazonS3PluginTest {
|
|||
when(mockConnection.listNextBatchOfObjects(mockObjectListing)).thenReturn(mockObjectListing);
|
||||
when(mockObjectListing.getObjectSummaries()).thenReturn(mockS3ObjectSummaryList);
|
||||
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
mockConnection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
|
|
@ -684,6 +755,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testListFilesWithUnsignedUrl() throws MalformedURLException {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -723,8 +795,9 @@ public class AmazonS3PluginTest {
|
|||
URL dummyUrl2 = new URL("http", "dummy_url_1", "");
|
||||
when(mockConnection.getUrl(anyString(), anyString())).thenReturn(dummyUrl1).thenReturn(dummyUrl2);
|
||||
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
mockConnection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
|
|
@ -761,6 +834,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testListFilesWithSignedUrl() throws MalformedURLException {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -800,8 +874,9 @@ public class AmazonS3PluginTest {
|
|||
URL dummyUrl2 = new URL("http", "dummy_url_1", "");
|
||||
when(mockConnection.generatePresignedUrl(any())).thenReturn(dummyUrl1).thenReturn(dummyUrl2);
|
||||
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
mockConnection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
|
|
@ -841,6 +916,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testListFilesWithSignedUrlAndNullDuration() throws MalformedURLException {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
|
|
@ -879,8 +955,9 @@ public class AmazonS3PluginTest {
|
|||
URL dummyUrl2 = new URL("http", "dummy_url_1", "");
|
||||
when(mockConnection.generatePresignedUrl(any())).thenReturn(dummyUrl1).thenReturn(dummyUrl2);
|
||||
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
mockConnection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
|
||||
|
|
@ -940,6 +1017,7 @@ public class AmazonS3PluginTest {
|
|||
@Test
|
||||
public void testListBuckets() {
|
||||
DatasourceConfiguration datasourceConfiguration = createDatasourceConfiguration();
|
||||
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
Bucket mockS3Bucket = mock(Bucket.class);
|
||||
mockS3Bucket.setName("dummy_bucket");
|
||||
|
|
@ -956,28 +1034,29 @@ public class AmazonS3PluginTest {
|
|||
AmazonS3 mockConnection = mock(AmazonS3.class);
|
||||
when(mockConnection.listBuckets()).thenReturn(List.of(mockS3Bucket));
|
||||
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.execute(
|
||||
mockConnection,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
Mono<ActionExecutionResult> resultMono = pluginExecutor.executeParameterized(
|
||||
mockConnection,
|
||||
executeActionDTO,
|
||||
datasourceConfiguration,
|
||||
actionConfiguration);
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(result -> {
|
||||
assertTrue(result.getIsExecutionSuccess());
|
||||
.assertNext(result -> {
|
||||
assertTrue(result.getIsExecutionSuccess());
|
||||
|
||||
Map<String, List<String>> node = (Map<String, List<String>>) result.getBody();
|
||||
List<String> buckets = node.get("bucketList");
|
||||
assertTrue(buckets.size() == 1);
|
||||
assertEquals(buckets.get(0), mockS3Bucket.getName());
|
||||
/*
|
||||
* - RequestParamDTO object only have attributes configProperty and value at this point.
|
||||
*/
|
||||
List<RequestParamDTO> expectedRequestParams = new ArrayList<>();
|
||||
expectedRequestParams.add(new RequestParamDTO("command", "LIST_BUCKETS",
|
||||
null, null, null)); // Action
|
||||
expectedRequestParams.add(new RequestParamDTO("bucket", null,
|
||||
null, null, null)); // Bucket name
|
||||
assertEquals(result.getRequest().getRequestParams().toString(), expectedRequestParams.toString());
|
||||
})
|
||||
Map<String, List<String>> node = (Map<String, List<String>>) result.getBody();
|
||||
List<String> buckets = node.get("bucketList");
|
||||
assertTrue(buckets.size() == 1);
|
||||
assertEquals(buckets.get(0), mockS3Bucket.getName());
|
||||
/*
|
||||
* - RequestParamDTO object only have attributes configProperty and value at this point.
|
||||
*/
|
||||
List<RequestParamDTO> expectedRequestParams = new ArrayList<>();
|
||||
expectedRequestParams.add(new RequestParamDTO("command", "LIST_BUCKETS",
|
||||
null, null, null)); // Action
|
||||
expectedRequestParams.add(new RequestParamDTO("bucket", null,
|
||||
null, null, null)); // Bucket name
|
||||
assertEquals(result.getRequest().getRequestParams().toString(), expectedRequestParams.toString());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user