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:
Nidhi 2021-11-15 10:57:41 +05:30 committed by GitHub
parent 7a2bd98ca0
commit 93de065fa8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 281 additions and 104 deletions

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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"
}
]
}
]
}

View File

@ -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();
}