Merge branch 'feature/onLoadActionDependencies' into 'release'

Page load actions also now contain all the dependent GET actions

See merge request theappsmith/internal-tools-server!182
This commit is contained in:
Trisha Anand 2020-01-30 09:48:48 +00:00
commit 9f13e199b9
3 changed files with 81 additions and 52 deletions

View File

@ -8,6 +8,7 @@ import lombok.Setter;
import lombok.ToString;
import net.minidev.json.JSONObject;
import java.util.List;
import java.util.Set;
@Getter
@ -29,14 +30,14 @@ public class Layout extends BaseDomain {
@Deprecated
Set<DslActionDTO> layoutActions;
Set<DslActionDTO> layoutOnLoadActions;
List<Set<DslActionDTO>> layoutOnLoadActions;
@Deprecated
@JsonIgnore
Set<DslActionDTO> publishedLayoutActions;
@JsonIgnore
Set<DslActionDTO> publishedLayoutOnLoadActions;
List<Set<DslActionDTO>> publishedLayoutOnLoadActions;
@JsonIgnore
Set<String> widgetNames;
@ -54,7 +55,7 @@ public class Layout extends BaseDomain {
return viewMode ? publishedLayoutActions : layoutActions;
}
public Set<DslActionDTO> getLayoutOnLoadActions() {
public List<Set<DslActionDTO>> getLayoutOnLoadActions() {
return viewMode ? publishedLayoutOnLoadActions : layoutOnLoadActions;
}
}

View File

@ -26,11 +26,14 @@ public enum AppsmithError {
PAGE_DOESNT_BELONG_TO_APPLICATION(400, 4018, "Page {0} does not belong to the application {1}"),
UNAUTHORIZED_DOMAIN(401, 4019, "Invalid email domain provided. Please sign in with a valid work email ID"),
INVALID_PASSWORD_RESET(400, 4020, "Unable to reset the password. Please initiate a request via 'forgot password' link to reset your password"),
NO_RESOURCE_FOUND(404, 4021, "Unable to find {0} with id {1}"),
UNAUTHORIZED_ACCESS(401, 4022, "Unauthorized access"),
INVALID_DATASOURCE_NAME(400, 4023, "Datasource name is invalid"),
DUPLICATE_KEY(409, 4024, "Unable to save the object in the database. Detailed error message: {0}"),
GENERIC_BAD_REQUEST(400, 4025, "Bad Request: {0}"),
LOGIN_INTERNAL_ERROR(401, 4021, "Internal error while trying to login"),
JSON_PROCESSING_ERROR(400, 4022, "Json processing error with error {0}"),
INVALID_CREDENTIALS(200, 4023, "Invalid credentials provided. Did you input the credentials correctly?"),
DUPLICATE_KEY(409, 4024, "Duplicate key error"),
UNAUTHORIZED_ACCESS(401, 4025, "Unauthorized access"),
INVALID_DATASOURCE_NAME(400, 4026, "Datasource name is invalid"),
NO_RESOURCE_FOUND(404, 4027, "Unable to find {0} with id {1}"),
GENERIC_BAD_REQUEST(400, 4028, "Bad Request: {0}"),
INTERNAL_SERVER_ERROR(500, 5000, "Internal server error while processing request"),
REPOSITORY_SAVE_FAILED(500, 5001, "Repository save failed"),
PLUGIN_INSTALLATION_FAILED_DOWNLOAD_ERROR(500, 5002, "Due to error in downloading the plugin from remote repository, plugin installation has failed. Check the jar location and try again"),

View File

@ -82,6 +82,7 @@ public class LayoutActionServiceImpl implements LayoutActionService {
dslString = objectMapper.writeValueAsString(dsl);
} catch (JsonProcessingException e) {
log.debug("Exception caught during conversion of DSL Json object to String. ", e);
Mono.error(new AppsmithException(AppsmithError.JSON_PROCESSING_ERROR, e.getMessage()));
}
Set<String> widgetNames = new HashSet<>();
@ -95,46 +96,23 @@ public class LayoutActionServiceImpl implements LayoutActionService {
Set<String> dynamicBindingNames = new HashSet<>();
if (!dynamicBindings.isEmpty()) {
for (String mustacheKey : dynamicBindings) {
String key = mustacheKey.trim();
// Extract all the words in the dynamic bindings
Matcher matcher = pattern.matcher(key);
while (matcher.find()) {
String word = matcher.group();
String[] subStrings = word.split(Pattern.quote("."));
if (subStrings.length > 0) {
// We are only interested in the top level. e.g. if its Input1.text, we want just Input1
dynamicBindingNames.add(subStrings[0]);
}
}
extractWordsAndAddToSet(dynamicBindingNames, mustacheKey);
}
}
return dynamicBindingNames;
});
Mono<Set<DslActionDTO>> onLoadActionsMono = dynamicBindingNamesMono
.flatMapMany(dynamicBindingNames -> findRestApiActionsByPageIdAndHTTPMethodGET(dynamicBindingNames, pageId))
.map(action -> {
// Since we are only interested in few fields, prepare the DslActionDTO that needs to be stored in
// the layout and return it to be collected in to a set.
DslActionDTO newAction = new DslActionDTO();
newAction.setId(action.getId());
newAction.setPluginType(action.getPluginType());
newAction.setJsonPathKeys(action.getJsonPathKeys());
newAction.setName(action.getName());
return newAction;
})
.collect(toSet());
List<Set<DslActionDTO>> onLoadActionsList = new ArrayList<>();
Mono<List<Set<DslActionDTO>>> onLoadActionsMono = dynamicBindingNamesMono
.flatMap(dynamicBindingNames -> findOnLoadActionsInPage(onLoadActionsList, dynamicBindingNames, pageId));
return pageService.findByIdAndLayoutsId(pageId, layoutId)
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID + " or " + FieldName.LAYOUT_ID)))
.zipWith(onLoadActionsMono)
.map(tuple -> {
Page page = tuple.getT1();
Set<DslActionDTO> onLoadActions = tuple.getT2();
List<Set<DslActionDTO>> onLoadActions = tuple.getT2();
List<Layout> layoutList = page.getLayouts();
@ -143,7 +121,7 @@ public class LayoutActionServiceImpl implements LayoutActionService {
if (storedLayout.getId().equals(layoutId)) {
//Copy the variables to conserve before update
JSONObject publishedDsl = storedLayout.getPublishedDsl();
Set<DslActionDTO> publishedLayoutOnLoadActions = storedLayout.getPublishedLayoutOnLoadActions();
List<Set<DslActionDTO>> publishedLayoutOnLoadActions = storedLayout.getPublishedLayoutOnLoadActions();
//Update
layout.setLayoutOnLoadActions(onLoadActions);
@ -171,6 +149,53 @@ public class LayoutActionServiceImpl implements LayoutActionService {
});
}
private Mono<List<Set<DslActionDTO>>> findOnLoadActionsInPage(List<Set<DslActionDTO>> onLoadActions, Set<String> dynamicBindingNames, String pageId) {
if (dynamicBindingNames == null || dynamicBindingNames.isEmpty()) {
return Mono.just(onLoadActions);
}
Set<String> bindingNames = new HashSet<>();
return findRestApiActionsByPageIdAndHTTPMethodGET(dynamicBindingNames, pageId)
.map(action -> {
for (String mustacheKey : action.getJsonPathKeys()) {
extractWordsAndAddToSet(bindingNames, mustacheKey);
}
DslActionDTO newAction = new DslActionDTO();
newAction.setId(action.getId());
newAction.setPluginType(action.getPluginType());
newAction.setJsonPathKeys(action.getJsonPathKeys());
newAction.setName(action.getName());
return newAction;
})
.collect(toSet())
.flatMap(actions -> {
Set<DslActionDTO> onLoadSet = new HashSet<>();
onLoadSet.addAll(actions);
// If the resultant set of actions is empty, don't add it to the array list.
if (!onLoadSet.isEmpty()) {
onLoadActions.add(0, onLoadSet);
}
return findOnLoadActionsInPage(onLoadActions, bindingNames, pageId);
});
}
private void extractWordsAndAddToSet(Set<String> bindingNames, String mustacheKey) {
String key = mustacheKey.trim();
// Extract all the words in the dynamic bindings
Matcher matcher = pattern.matcher(key);
while (matcher.find()) {
String word = matcher.group();
String[] subStrings = word.split(Pattern.quote("."));
if (subStrings.length > 0) {
// We are only interested in the top level. e.g. if its Input1.text, we want just Input1
bindingNames.add(subStrings[0]);
}
}
}
/**
* Given a list of names of actions (nodes) and pageId, it hits the database and returns all the actions matching
* this criteria of name and pageId with http method 'GET'
@ -206,19 +231,19 @@ public class LayoutActionServiceImpl implements LayoutActionService {
.flatMap(savedAction -> pageService
.findById(oldPageId)
.map(page -> {
if (page.getLayouts() == null) {
return Mono.empty();
}
if (page.getLayouts() == null) {
return Mono.empty();
}
return page.getLayouts()
.stream()
/*
* subscribe() is being used here because within a stream, the master subscriber provided
* by spring framework does not get attached here leading to the updateLayout mono not
* emitting. The same is true for the updateLayout call for the new page.
*/
.map(layout -> updateLayout(oldPageId, layout.getId(), layout).subscribe())
.collect(toSet());
return page.getLayouts()
.stream()
/*
* subscribe() is being used here because within a stream, the master subscriber provided
* by spring framework does not get attached here leading to the updateLayout mono not
* emitting. The same is true for the updateLayout call for the new page.
*/
.map(layout -> updateLayout(oldPageId, layout.getId(), layout).subscribe())
.collect(toSet());
})
.then(pageService.findById(actionMoveDTO.getDestinationPageId()))
.map(page -> {
@ -227,9 +252,9 @@ public class LayoutActionServiceImpl implements LayoutActionService {
}
return page.getLayouts()
.stream()
.map(layout -> updateLayout(actionMoveDTO.getDestinationPageId(), layout.getId(), layout).subscribe())
.collect(toSet());
.stream()
.map(layout -> updateLayout(actionMoveDTO.getDestinationPageId(), layout.getId(), layout).subscribe())
.collect(toSet());
})
.thenReturn(savedAction));
}