Rename isExecuteOnLoad to executeOnLoad.

The `is` prefix apparently makes Spring unhappy.
This commit is contained in:
Shrikant Kandula 2020-05-18 12:13:54 +00:00
parent 98c38df397
commit c4d3d535a1
6 changed files with 148 additions and 31 deletions

View File

@ -33,6 +33,8 @@ public class Action extends BaseDomain {
PluginType pluginType;
Boolean executeOnLoad;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
Boolean isValid;

View File

@ -16,5 +16,9 @@ public interface ActionRepository extends BaseRepository<Action, String> {
Flux<Action> findByPageId(String pageId);
Flux<Action> findDistinctActionsByNameInAndPageIdAndActionConfiguration_HttpMethod(Set<String> names, String pageId, String httpMethod);
Flux<Action> findDistinctActionsByNameInAndPageIdAndActionConfiguration_HttpMethod(
Set<String> names, String pageId, String httpMethod);
Flux<Action> findDistinctActionsByNameInAndPageIdAndExecuteOnLoadTrue(
Set<String> names, String pageId);
}

View File

@ -17,7 +17,7 @@ public interface ActionService extends CrudService<Action, String> {
Mono<Action> findByNameAndPageId(String name, String pageId);
Flux<Action> findDistinctRestApiActionsByNameInAndPageIdAndHttpMethod(Set<String> names, String pageId, String httpMethod);
Flux<Action> findOnLoadActionsInPage(Set<String> names, String pageId);
Mono<Action> validateAndSaveActionToRepository(Action action);

View File

@ -464,9 +464,23 @@ public class ActionServiceImpl extends BaseService<ActionRepository, Action, Str
return repository.findByNameAndPageId(name, pageId);
}
/**
* Given a list of names of actions and pageId, find all the actions matching this criteria of name, pageId, http
* method 'GET' (for API actions only) or have isExecuteOnLoad be true.
*
* @param names Set of Action names. The returned list of actions will be a subset of the actioned named in this set.
* @param pageId Id of the Page within which to look for Actions.
* @return A Flux of Actions that are identified to be executed on page-load.
*/
@Override
public Flux<Action> findDistinctRestApiActionsByNameInAndPageIdAndHttpMethod(Set<String> names, String pageId, String httpMethod) {
return repository.findDistinctActionsByNameInAndPageIdAndActionConfiguration_HttpMethod(names, pageId, httpMethod);
public Flux<Action> findOnLoadActionsInPage(Set<String> names, String pageId) {
final Flux<Action> getApiActions = repository
.findDistinctActionsByNameInAndPageIdAndActionConfiguration_HttpMethod(names, pageId, "GET");
final Flux<Action> explicitOnLoadActions = repository
.findDistinctActionsByNameInAndPageIdAndExecuteOnLoadTrue(names, pageId);
return getApiActions.concatWith(explicitOnLoadActions);
}
/**

View File

@ -22,7 +22,6 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
@ -75,8 +74,6 @@ public class LayoutActionServiceImpl implements LayoutActionService {
@Override
public Mono<Layout> updateLayout(String pageId, String layoutId, Layout layout) {
String dslString = "";
JSONObject dsl = layout.getDsl();
if (dsl == null) {
// There is no DSL here. No need to process anything. Return as is.
@ -84,11 +81,12 @@ public class LayoutActionServiceImpl implements LayoutActionService {
}
// Convert the DSL into a String
String dslString;
try {
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()));
return Mono.error(new AppsmithException(AppsmithError.JSON_PROCESSING_ERROR, e.getMessage()));
}
Set<String> widgetNames = new HashSet<>();
@ -109,9 +107,8 @@ public class LayoutActionServiceImpl implements LayoutActionService {
return dynamicBindingNames;
});
List<HashSet<DslActionDTO>> onLoadActionsList = new ArrayList<>();
Mono<List<HashSet<DslActionDTO>>> onLoadActionsMono = dynamicBindingNamesMono
.flatMap(dynamicBindingNames -> findOnLoadActionsInPage(onLoadActionsList, dynamicBindingNames, pageId));
.flatMap(dynamicBindingNames -> findOnLoadActionsInPage(dynamicBindingNames, pageId));
return pageService.findByIdAndLayoutsId(pageId, layoutId)
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID + " or " + FieldName.LAYOUT_ID)))
@ -155,20 +152,22 @@ public class LayoutActionServiceImpl implements LayoutActionService {
});
}
public Mono<List<HashSet<DslActionDTO>>> findOnLoadActionsInPage(Set<String> dynamicBindingNames, String pageId) {
return findOnLoadActionsInPage(new ArrayList<>(), dynamicBindingNames, pageId);
}
private Mono<List<HashSet<DslActionDTO>>> findOnLoadActionsInPage(List<HashSet<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)
return actionService.findOnLoadActionsInPage(dynamicBindingNames, pageId)
.map(action -> {
if (action.getJsonPathKeys() != null) {
if (!CollectionUtils.isEmpty(action.getJsonPathKeys())) {
for (String mustacheKey : action.getJsonPathKeys()) {
extractWordsAndAddToSet(bindingNames, mustacheKey);
}
if (bindingNames.contains(action.getName())) {
bindingNames.remove(action.getName());
}
bindingNames.remove(action.getName());
}
DslActionDTO newAction = new DslActionDTO();
newAction.setId(action.getId());
@ -182,8 +181,7 @@ public class LayoutActionServiceImpl implements LayoutActionService {
})
.collect(toSet())
.flatMap(actions -> {
HashSet<DslActionDTO> onLoadSet = new HashSet<>();
onLoadSet.addAll(actions);
HashSet<DslActionDTO> onLoadSet = new HashSet<>(actions);
// If the resultant set of actions is empty, don't add it to the array list.
if (!onLoadSet.isEmpty()) {
@ -210,20 +208,6 @@ public class LayoutActionServiceImpl implements LayoutActionService {
}
}
/**
* 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'
*
* @param nodes
* @param pageId
* @return
*/
Flux<Action> findRestApiActionsByPageIdAndHTTPMethodGET(Set<String> nodes, String pageId) {
return actionService
.findDistinctRestApiActionsByNameInAndPageIdAndHttpMethod(nodes, pageId, "GET");
}
@Override
public Mono<Action> moveAction(ActionMoveDTO actionMoveDTO) {
Action action = actionMoveDTO.getAction();

View File

@ -1,9 +1,12 @@
package com.appsmith.server.services;
import com.appsmith.external.models.ActionConfiguration;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.Action;
import com.appsmith.server.domains.Application;
import com.appsmith.server.domains.Layout;
import com.appsmith.server.domains.Page;
import com.appsmith.server.dtos.DslActionDTO;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import lombok.extern.slf4j.Slf4j;
@ -14,13 +17,19 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpMethod;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
@ -41,6 +50,9 @@ public class LayoutServiceTest {
@Autowired
LayoutActionService layoutActionService;
@Autowired
ActionService actionService;
Mono<Layout> layoutMono;
Mono<Application> applicationMono;
@ -179,6 +191,107 @@ public class LayoutServiceTest {
.verifyComplete();
}
@Test
@WithUserDetails(value = "api_user")
public void getActionsExecuteOnLoad() {
Mono<Layout> testMono = pageService
.findByName("validPageName")
.flatMap(page1 -> {
List<Mono<Action>> monos = new ArrayList<>();
Action action = new Action();
action.setName("aGetAction");
action.setActionConfiguration(new ActionConfiguration());
action.getActionConfiguration().setHttpMethod(HttpMethod.GET);
action.setPageId(page1.getId());
monos.add(actionService.create(action));
action = new Action();
action.setName("aPostAction");
action.setActionConfiguration(new ActionConfiguration());
action.getActionConfiguration().setHttpMethod(HttpMethod.POST);
action.setPageId(page1.getId());
monos.add(actionService.create(action));
action = new Action();
action.setName("aPostActionWithAutoExec");
action.setActionConfiguration(new ActionConfiguration());
action.getActionConfiguration().setHttpMethod(HttpMethod.POST);
action.getActionConfiguration().setBody(
"this won't be auto-executed: {{aPostSecondaryAction.data}}, but this one will be: {{aPostTertiaryAction.data}}.");
action.setJsonPathKeys(Set.of("aPostSecondaryAction.data", "aPostTertiaryAction.data"));
action.setPageId(page1.getId());
action.setExecuteOnLoad(true);
monos.add(actionService.create(action));
action = new Action();
action.setName("aPostSecondaryAction");
action.setActionConfiguration(new ActionConfiguration());
action.getActionConfiguration().setHttpMethod(HttpMethod.POST);
action.setPageId(page1.getId());
monos.add(actionService.create(action));
action = new Action();
action.setName("aPostTertiaryAction");
action.setActionConfiguration(new ActionConfiguration());
action.getActionConfiguration().setHttpMethod(HttpMethod.POST);
action.setPageId(page1.getId());
action.setExecuteOnLoad(true);
monos.add(actionService.create(action));
action = new Action();
action.setName("aDeleteAction");
action.setActionConfiguration(new ActionConfiguration());
action.getActionConfiguration().setHttpMethod(HttpMethod.DELETE);
action.setPageId(page1.getId());
monos.add(actionService.create(action));
return Mono.zip(monos, objects -> page1);
})
.zipWhen(page1 -> {
Layout layout = new Layout();
JSONObject obj = new JSONObject(Map.of(
"key", "value"
));
layout.setDsl(obj);
return layoutService.createLayout(page1.getId(), layout);
})
.flatMap(tuple2 -> {
final Page page1 = tuple2.getT1();
final Layout layout = tuple2.getT2();
Layout newLayout = new Layout();
JSONObject obj = new JSONObject(Map.of(
"key", "value-updated",
"another", "Hello people of the {{input1.text}} planet!",
"dynamicGet", "some dynamic {{aGetAction.data}}",
"dynamicPost", "some dynamic {{aPostAction.data}}",
"dynamicPostWithAutoExec", "some dynamic {{aPostActionWithAutoExec.data}}",
"dynamicDelete", "some dynamic {{aDeleteAction.data}}"
));
newLayout.setDsl(obj);
return layoutActionService.updateLayout(page1.getId(), layout.getId(), newLayout);
});
StepVerifier
.create(testMono)
.assertNext(layout -> {
assertThat(layout).isNotNull();
assertThat(layout.getId()).isNotNull();
assertThat(layout.getDsl().get("key")).isEqualTo("value-updated");
assertThat(layout.getLayoutOnLoadActions()).hasSize(2);
assertThat(layout.getLayoutOnLoadActions().get(0).stream().map(DslActionDTO::getName).collect(Collectors.toSet()))
.hasSameElementsAs(Set.of("aPostTertiaryAction"));
assertThat(layout.getLayoutOnLoadActions().get(1).stream().map(DslActionDTO::getName).collect(Collectors.toSet()))
.hasSameElementsAs(Set.of("aGetAction", "aPostActionWithAutoExec"));
})
.verifyComplete();
}
@After
public void purgePages() {
pageService.deleteAll();