chore: refactor crud page flow to move plugin specific handling to plugin module (#26287)
This commit is contained in:
parent
d26ae16bca
commit
a8dcedac7b
|
|
@ -21,6 +21,7 @@ import reactor.core.scheduler.Schedulers;
|
|||
import reactor.util.function.Tuple2;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
|
@ -313,4 +314,15 @@ public interface PluginExecutor<C> extends ExtensionPoint, CrudTemplateService {
|
|||
default Mono<DatasourceConfiguration> getDatasourceMetadata(DatasourceConfiguration datasourceConfiguration) {
|
||||
return Mono.just(datasourceConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is supposed to provide help with any update required to template queries that are used to create
|
||||
* the actual select, updated, insert etc. queries as part of the generate CRUD page feature. Any plugin that
|
||||
* needs special handling should override this method. e.g. in case of the S3 plugin some special handling is
|
||||
* required because (a) it uses UQI config form (b) it has concept of bucket instead of table.
|
||||
*/
|
||||
default Mono<Void> sanitizeGenerateCRUDPageTemplateInfo(
|
||||
List<ActionConfiguration> actionConfigurationList, Object... args) {
|
||||
return Mono.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ 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;
|
||||
import static com.external.plugins.constants.FieldName.CREATE_EXPIRY;
|
||||
import static com.external.plugins.constants.FieldName.KEY_BUCKET;
|
||||
import static com.external.plugins.constants.FieldName.KEY_DATA;
|
||||
import static com.external.plugins.constants.FieldName.LIST_EXPIRY;
|
||||
import static com.external.plugins.constants.FieldName.LIST_PAGINATE;
|
||||
import static com.external.plugins.constants.FieldName.LIST_PREFIX;
|
||||
|
|
@ -110,6 +112,7 @@ import static com.external.plugins.constants.S3PluginConstants.YES;
|
|||
import static com.external.utils.DatasourceUtils.getS3ClientBuilder;
|
||||
import static com.external.utils.TemplateUtils.getTemplates;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static org.apache.commons.collections.CollectionUtils.isEmpty;
|
||||
|
||||
@Slf4j
|
||||
public class AmazonS3Plugin extends BasePlugin {
|
||||
|
|
@ -1035,5 +1038,28 @@ public class AmazonS3Plugin extends BasePlugin {
|
|||
.upload(bucketName, path, inputStream, objectMetadata)
|
||||
.waitForUploadResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is supposed to provide help with any update required to template queries that are used to create
|
||||
* the actual select, updated, insert etc. queries as part of the generate CRUD page feature. Any plugin that
|
||||
* needs special handling should override this method. e.g. in case of the S3 plugin some special handling is
|
||||
* required because (a) it uses UQI config form (b) it has concept of bucket instead of table.
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> sanitizeGenerateCRUDPageTemplateInfo(
|
||||
List<ActionConfiguration> actionConfigurationList, Object... args) {
|
||||
if (isEmpty(actionConfigurationList)) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
/* Add mapping to replace template bucket name with user chosen bucket everywhere in the template */
|
||||
Map<String, String> mappedColumnsAndTableName = (Map<String, String>) args[0];
|
||||
final String userSelectedBucketName = (String) args[1];
|
||||
Map<String, Object> formData = actionConfigurationList.get(0).getFormData();
|
||||
mappedColumnsAndTableName.put(
|
||||
(String) ((Map<?, ?>) formData.get(KEY_BUCKET)).get(KEY_DATA), userSelectedBucketName);
|
||||
|
||||
return Mono.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,4 +36,6 @@ public class FieldName {
|
|||
public static final String LIST_SORT = LIST + "." + SORT;
|
||||
public static final String LIST_PAGINATE = LIST + "." + PAGINATE;
|
||||
public static final String SMART_SUBSTITUTION = "smartSubstitution";
|
||||
public static final String KEY_BUCKET = "bucket";
|
||||
public static final String KEY_DATA = "data";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ import static org.mockito.Mockito.doReturn;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.util.CollectionUtils.isEmpty;
|
||||
|
||||
@Slf4j
|
||||
public class AmazonS3PluginTest {
|
||||
|
|
@ -1497,4 +1498,32 @@ public class AmazonS3PluginTest {
|
|||
.assertNext(result -> assertEquals(0, result.getInvalids().size()))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verify_sanitizeGenerateCRUDPageTemplateInfo_doesNothing_onEmptyActionConfig() {
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
List<ActionConfiguration> actionConfigurationList = new ArrayList<>();
|
||||
Map<String, String> mappedColumnsAndTableName = new HashMap<>();
|
||||
pluginExecutor
|
||||
.sanitizeGenerateCRUDPageTemplateInfo(actionConfigurationList, mappedColumnsAndTableName, "test")
|
||||
.block();
|
||||
assertEquals(0, actionConfigurationList.size());
|
||||
assertEquals(true, isEmpty(mappedColumnsAndTableName));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verify_sanitizeGenerateCRUDPageTemplateInfo_addsInfoToReplaceTemplateBucket_withUserSelectedBucket() {
|
||||
Map<String, String> mappedColumnsAndTableName = new HashMap<>();
|
||||
String userSelectedBucketName = "userBucket";
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
Map<String, Object> formData = new HashMap<>();
|
||||
setDataValueSafelyInFormData(formData, "bucket", "templateBucket");
|
||||
actionConfiguration.setFormData(formData);
|
||||
AmazonS3Plugin.S3PluginExecutor pluginExecutor = new AmazonS3Plugin.S3PluginExecutor();
|
||||
pluginExecutor
|
||||
.sanitizeGenerateCRUDPageTemplateInfo(
|
||||
List.of(actionConfiguration), mappedColumnsAndTableName, userSelectedBucketName)
|
||||
.block();
|
||||
assertEquals(userSelectedBucketName, mappedColumnsAndTableName.get("templateBucket"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -387,24 +387,26 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio
|
|||
.peek(newAction -> newAction.setDefaultResources(page.getDefaultResources()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Extract S3 bucket name from template application and map to users bucket. Bucket name is stored
|
||||
// at
|
||||
// index 1 in plugin specified templates
|
||||
List<ActionConfiguration> templateUnpublishedActionConfigList = templateActionList.stream()
|
||||
.map(NewAction::getUnpublishedAction)
|
||||
.map(ActionDTO::getActionConfiguration)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (Entity.S3_PLUGIN_PACKAGE_NAME.equals(plugin.getPackageName())
|
||||
&& !CollectionUtils.isEmpty(templateActionList)) {
|
||||
final Map<String, Object> formData = templateActionList
|
||||
.get(0)
|
||||
.getUnpublishedAction()
|
||||
.getActionConfiguration()
|
||||
.getFormData();
|
||||
mappedColumnsAndTableName.put(
|
||||
(String) ((Map<?, ?>) formData.get("bucket")).get("data"), tableName);
|
||||
}
|
||||
/**
|
||||
* Any plugin specific update to the template queries should be defined by overriding the
|
||||
* `sanitizeGenerateCRUDPageTemplateInfo` method in the respective plugin. In the default case no
|
||||
* changes are made to the template. e.g. please check the sanitizeGenerateCRUDPageTemplateInfo
|
||||
* method defined in AmazonS3Plugin.java .
|
||||
*/
|
||||
Mono<Void> sanitizeTemplateInfoMono = pluginExecutorHelper
|
||||
.getPluginExecutorFromPackageName(plugin.getPackageName())
|
||||
.flatMap(pluginExecutor -> pluginExecutor.sanitizeGenerateCRUDPageTemplateInfo(
|
||||
templateUnpublishedActionConfigList, mappedColumnsAndTableName, tableName));
|
||||
|
||||
log.debug("Going to update layout for page {} and layout {}", savedPageId, layoutId);
|
||||
return layoutActionService
|
||||
.updateLayout(savedPageId, page.getApplicationId(), layoutId, layout)
|
||||
return sanitizeTemplateInfoMono
|
||||
.then(layoutActionService.updateLayout(
|
||||
savedPageId, page.getApplicationId(), layoutId, layout))
|
||||
.then(Mono.zip(
|
||||
Mono.just(datasourceStorage),
|
||||
Mono.just(templateActionList),
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.appsmith.external.models.DatasourceStructure.Table;
|
|||
import com.appsmith.external.models.DatasourceStructure.TableType;
|
||||
import com.appsmith.external.models.DefaultResources;
|
||||
import com.appsmith.external.models.Property;
|
||||
import com.appsmith.external.plugins.PluginExecutor;
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.domains.Application;
|
||||
import com.appsmith.server.domains.GitApplicationMetadata;
|
||||
|
|
@ -60,6 +61,9 @@ import java.util.UUID;
|
|||
|
||||
import static com.appsmith.server.acl.AclPermission.READ_PAGES;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
@Slf4j
|
||||
@ExtendWith(SpringExtension.class)
|
||||
|
|
@ -158,16 +162,18 @@ public class CreateDBTablePageSolutionTests {
|
|||
@MockBean
|
||||
private PluginExecutorHelper pluginExecutorHelper;
|
||||
|
||||
private PluginExecutor spyMockPluginExecutor = spy(new MockPluginExecutor());
|
||||
|
||||
private final CRUDPageResourceDTO resource = new CRUDPageResourceDTO();
|
||||
|
||||
@BeforeEach
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void setup() {
|
||||
|
||||
Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any()))
|
||||
.thenReturn(Mono.just(new MockPluginExecutor()));
|
||||
Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(spyMockPluginExecutor));
|
||||
Mockito.when(pluginExecutorHelper.getPluginExecutorFromPackageName(Mockito.anyString()))
|
||||
.thenReturn(Mono.just(new MockPluginExecutor()));
|
||||
.thenReturn(Mono.just(spyMockPluginExecutor))
|
||||
.thenReturn(Mono.just(spyMockPluginExecutor));
|
||||
|
||||
if (testWorkspace == null) {
|
||||
Workspace workspace = new Workspace();
|
||||
|
|
@ -905,6 +911,21 @@ public class CreateDBTablePageSolutionTests {
|
|||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void createPageWithNullPageIdForS3() {
|
||||
/**
|
||||
* Define handling for sanitizeGenerateCRUDPageTemplateInfo method for S3 plugin on spyMockPluginExecutor.
|
||||
*/
|
||||
doAnswer(invocation -> {
|
||||
List<ActionConfiguration> actionConfigurationList = invocation.getArgument(0);
|
||||
Map<String, String> mappedColumnsAndTableName = invocation.getArgument(1);
|
||||
String bucketName = invocation.getArgument(2);
|
||||
Map<String, Object> formData =
|
||||
actionConfigurationList.get(0).getFormData();
|
||||
mappedColumnsAndTableName.put(
|
||||
(String) ((Map<?, ?>) formData.get("bucket")).get("data"), bucketName);
|
||||
return Mono.empty();
|
||||
})
|
||||
.when(spyMockPluginExecutor)
|
||||
.sanitizeGenerateCRUDPageTemplateInfo(any(), any(), any());
|
||||
|
||||
resource.setApplicationId(testApp.getId());
|
||||
StringBuilder pluginName = new StringBuilder();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user