diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java index 566de8ec21..8cb3878d1d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java @@ -29,7 +29,6 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; -import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; @@ -46,11 +45,9 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNewFieldValuesIntoOldObject; import static java.lang.Boolean.TRUE; -import static java.util.stream.Collectors.toMap; @Slf4j public class ActionCollectionServiceCEImpl extends BaseService @@ -171,17 +168,12 @@ public class ActionCollectionServiceCEImpl extends BaseService populateActionCollectionByViewMode( ActionCollectionDTO actionCollectionDTO1, Boolean viewMode) { - return Mono.just(actionCollectionDTO1).flatMap(actionCollectionDTO -> Flux.fromIterable( - actionCollectionDTO.getDefaultToBranchedActionIdsMap().values()) - .mergeWith(Flux.fromIterable(actionCollectionDTO - .getDefaultToBranchedArchivedActionIdsMap() - .values())) - .flatMap(actionId -> { - return newActionService.findActionDTObyIdAndViewMode( - actionId, viewMode, actionPermission.getReadPermission()); - }) + return newActionService + .findByCollectionIdAndViewMode( + actionCollectionDTO1.getId(), viewMode, actionPermission.getReadPermission()) + .map(action -> newActionService.generateActionByViewMode(action, false)) .collectList() - .flatMap(actionsList -> splitValidActionsByViewMode(actionCollectionDTO, actionsList, viewMode))); + .flatMap(actionsList -> splitValidActionsByViewMode(actionCollectionDTO1, actionsList, viewMode)); } /** @@ -191,28 +183,17 @@ public class ActionCollectionServiceCEImpl extends BaseService splitValidActionsByViewMode( ActionCollectionDTO actionCollectionDTO, List actionsList, Boolean viewMode) { return Mono.just(actionCollectionDTO).map(actionCollectionDTO1 -> { - List archivedActionList = new ArrayList<>(); - List validActionList = new ArrayList<>(); final List collect = actionsList.stream() .parallel() .map(ActionDTO::getPluginId) .distinct() - .collect(Collectors.toList()); + .toList(); if (collect.size() == 1) { actionCollectionDTO.setPluginId(collect.get(0)); actionCollectionDTO.setPluginType(actionsList.get(0).getPluginType()); } - actionsList.forEach(action -> { - if (action.getDeletedAt() == null) { - validActionList.add(action); - } else { - archivedActionList.add(action); - } - }); + List validActionList = new ArrayList<>(actionsList); actionCollectionDTO.setActions(validActionList); - if (Boolean.FALSE.equals(viewMode)) { - actionCollectionDTO.setArchivedActions(archivedActionList); - } return actionCollectionDTO; }); } @@ -273,9 +254,9 @@ public class ActionCollectionServiceCEImpl extends BaseService newActionService.findActionDTObyIdAndViewMode(actionId, viewMode, aclPermission)) + return newActionService + .findByCollectionIdAndViewMode(actionCollection.getId(), viewMode, aclPermission) + .map(action -> newActionService.generateActionByViewMode(action, false)) .collectList() .map(actionDTOList -> { actionCollectionViewDTO.setActions(actionDTOList); @@ -395,16 +376,15 @@ public class ActionCollectionServiceCEImpl extends BaseService newActionService - .deleteUnpublishedActionWithOptionalPermission(actionId, deleteActionPermission) + modifiedActionCollectionMono = newActionService + .findByCollectionIdAndViewMode(id, false, deleteActionPermission.orElse(null)) + .flatMap(newAction -> newActionService + .deleteGivenNewAction(newAction) // return an empty action so that the filter can remove it from the list .onErrorResume(throwable -> { log.debug( "Failed to delete action with id {} for collection: {}", - actionId, + newAction.getId(), toDelete.getUnpublishedCollection() .getName()); log.error(throwable.getMessage()); @@ -482,28 +462,7 @@ public class ActionCollectionServiceCEImpl extends BaseService { - Set actionIds = new HashSet<>(); - actionIds.addAll(actionCollection - .getUnpublishedCollection() - .getDefaultToBranchedActionIdsMap() - .values()); - if (actionCollection.getPublishedCollection() != null - && !CollectionUtils.isEmpty( - actionCollection.getPublishedCollection().getDefaultToBranchedActionIdsMap())) { - actionIds.addAll(actionCollection - .getPublishedCollection() - .getDefaultToBranchedActionIdsMap() - .values()); - } - return Flux.fromIterable(actionIds) - .flatMap(newActionService::archiveById) - .onErrorResume(throwable -> { - log.error(throwable.getMessage()); - return Mono.empty(); - }) - .then(repository.archive(actionCollection)); - }) + .flatMap(this::archiveGivenActionCollection) .collectList(); } @@ -539,43 +498,29 @@ public class ActionCollectionServiceCEImpl extends BaseService { - final ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - final ActionCollectionDTO publishedCollection = actionCollection.getPublishedCollection(); - final Set actionIds = new HashSet<>(); - if (unpublishedCollection != null) { - actionIds.addAll(unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .values()); - actionIds.addAll(unpublishedCollection - .getDefaultToBranchedArchivedActionIdsMap() - .values()); - } - if (publishedCollection != null - && !CollectionUtils.isEmpty(publishedCollection.getDefaultToBranchedActionIdsMap())) { - actionIds.addAll(publishedCollection - .getDefaultToBranchedActionIdsMap() - .values()); - actionIds.addAll(publishedCollection - .getDefaultToBranchedArchivedActionIdsMap() - .values()); - } - return actionIds; - }) - .flatMapMany(Flux::fromIterable) - .flatMap(actionId -> newActionService - .archiveById(actionId) + return actionCollectionMono.flatMap(this::archiveGivenActionCollection); + } + + protected Mono archiveGivenActionCollection(ActionCollection actionCollection) { + Flux unpublishedJsActionsFlux = newActionService.findByCollectionIdAndViewMode( + actionCollection.getId(), false, actionPermission.getDeletePermission()); + Flux publishedJsActionsFlux = newActionService.findByCollectionIdAndViewMode( + actionCollection.getId(), true, actionPermission.getDeletePermission()); + return unpublishedJsActionsFlux + .mergeWith(publishedJsActionsFlux) + .flatMap(toArchive -> newActionService + .archiveGivenNewAction(toArchive) // return an empty action so that the filter can remove it from the list .onErrorResume(throwable -> { - log.debug("Failed to delete action with id {} for collection with id: {}", actionId, id); + log.debug( + "Failed to delete action with id {} for collection with id: {}", + toArchive.getId(), + actionCollection.getId()); log.error(throwable.getMessage()); return Mono.empty(); })) .collectList() - .flatMap(actionList -> actionCollectionMono) - .flatMap( - actionCollection -> repository.archive(actionCollection).thenReturn(actionCollection)) + .then(repository.archive(actionCollection).thenReturn(actionCollection)) .flatMap(deletedActionCollection -> analyticsService.sendDeleteEvent( deletedActionCollection, getAnalyticsProperties(deletedActionCollection))); } @@ -856,10 +801,6 @@ public class ActionCollectionServiceCEImpl extends BaseService actionIds = actions.stream() - .collect(toMap(actionDTO -> actionDTO.getDefaultResources().getActionId(), ActionDTO::getId)); - collectionDTO.setDefaultToBranchedActionIdsMap(actionIds); } @Override diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceCEImpl.java index b6e6b6d718..ac773365e7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceCEImpl.java @@ -6,15 +6,12 @@ import com.appsmith.server.clonepage.ClonePageServiceCE; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.dtos.ClonePageMetaDTO; -import com.appsmith.server.newactions.base.NewActionService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties; @@ -23,7 +20,6 @@ import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullP @RequiredArgsConstructor public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceCE { private final ActionCollectionService actionCollectionService; - private final NewActionService newActionService; @Override public Mono cloneEntities(ClonePageMetaDTO clonePageMetaDTO) { @@ -49,54 +45,6 @@ public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceC defaultResourcesForDTO.setPageId(clonedPageDefaultResources.getPageId()); toBeClonedActionCollection.getUnpublishedCollection().setDefaultResources(defaultResourcesForDTO); - // Replace all action Ids from map - Map updatedDefaultToBranchedActionId = new HashMap<>(); - // Check if the application is connected with git and update - // defaultActionIds accordingly - // - // 1. If the app is connected with git keep the actionDefaultId as it is and - // update branchedActionId only - // - // 2. If app is not connected then both default and branchedActionId will be - // same as newly created action Id - - if (StringUtils.isEmpty(clonedPageDefaultResources.getBranchName())) { - unpublishedCollection.getDefaultToBranchedActionIdsMap().forEach((defaultId, oldActionId) -> { - // Filter out the actionIds for which the reference is not - // present in cloned actions, this happens when we have - // deleted action in unpublished mode - if (StringUtils.hasLength(oldActionId) - && StringUtils.hasLength(clonePageMetaDTO - .getOldToNewActionIdMap() - .get(oldActionId))) { - updatedDefaultToBranchedActionId.put( - clonePageMetaDTO - .getOldToNewActionIdMap() - .get(oldActionId), - clonePageMetaDTO - .getOldToNewActionIdMap() - .get(oldActionId)); - } - }); - } else { - unpublishedCollection.getDefaultToBranchedActionIdsMap().forEach((defaultId, oldActionId) -> { - // Filter out the actionIds for which the reference is not - // present in cloned actions, this happens when we have - // deleted action in unpublished mode - if (StringUtils.hasLength(defaultId) - && StringUtils.hasLength(clonePageMetaDTO - .getOldToNewActionIdMap() - .get(oldActionId))) { - updatedDefaultToBranchedActionId.put( - defaultId, - clonePageMetaDTO - .getOldToNewActionIdMap() - .get(oldActionId)); - } - }); - } - unpublishedCollection.setDefaultToBranchedActionIdsMap(updatedDefaultToBranchedActionId); - // Set id as null, otherwise create (which is using under the hood save) // will try to overwrite same resource instead of creating a new resource toBeClonedActionCollection.setId(null); @@ -110,7 +58,9 @@ public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceC return actionCollectionService .create(toBeClonedActionCollection) .flatMap(clonedActionCollection -> { - clonePageMetaDTO.getClonedActionCollections().add(clonedActionCollection); + clonePageMetaDTO + .getOldToNewCollectionIds() + .put(sourceActionCollection.getId(), clonedActionCollection.getId()); if (!StringUtils.hasLength(clonedActionCollection .getDefaultResources() .getCollectionId())) { @@ -127,32 +77,6 @@ public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceC .then(); } - @Override - public Mono updateClonedEntities(ClonePageMetaDTO clonePageMetaDTO) { - return Flux.fromIterable(clonePageMetaDTO.getClonedActionCollections()) - .flatMap(clonedActionCollection -> { - return Flux.fromIterable(clonedActionCollection - .getUnpublishedCollection() - .getDefaultToBranchedActionIdsMap() - .values()) - .flatMap(newActionService::findById) - .flatMap(newlyCreatedAction -> { - newlyCreatedAction - .getUnpublishedAction() - .setCollectionId(clonedActionCollection.getId()); - newlyCreatedAction - .getUnpublishedAction() - .getDefaultResources() - .setCollectionId(clonedActionCollection - .getDefaultResources() - .getCollectionId()); - return newActionService.update(newlyCreatedAction.getId(), newlyCreatedAction); - }); - }) - .collectList() - .then(); - } - protected Flux getCloneableActionCollections(String pageId) { return actionCollectionService.findByPageId(pageId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceImpl.java index 5dabbf95db..f8cbdc8cbf 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceImpl.java @@ -3,14 +3,12 @@ package com.appsmith.server.actioncollections.clonepage; import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.clonepage.ClonePageService; import com.appsmith.server.domains.ActionCollection; -import com.appsmith.server.newactions.base.NewActionService; import org.springframework.stereotype.Service; @Service public class ActionCollectionClonePageServiceImpl extends ActionCollectionClonePageServiceCEImpl implements ClonePageService { - public ActionCollectionClonePageServiceImpl( - ActionCollectionService actionCollectionService, NewActionService newActionService) { - super(actionCollectionService, newActionService); + public ActionCollectionClonePageServiceImpl(ActionCollectionService actionCollectionService) { + super(actionCollectionService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/ActionCollectionImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/ActionCollectionImportableServiceCEImpl.java index 9f18888299..7213df99e9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/ActionCollectionImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/ActionCollectionImportableServiceCEImpl.java @@ -279,10 +279,6 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic final String fallbackDefaultContextId = unpublishedCollection.calculateContextId(); if (unpublishedCollection.getName() != null) { - unpublishedCollection.setDefaultToBranchedActionIdsMap(mappedImportableResourcesDTO - .getActionResultDTO() - .getUnpublishedCollectionIdToActionIdsMap() - .get(idFromJsonFile)); unpublishedCollection.setPluginId( mappedImportableResourcesDTO.getPluginMap().get(unpublishedCollection.getPluginId())); @@ -291,10 +287,6 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic } if (publishedCollection != null && publishedCollection.getName() != null) { - publishedCollection.setDefaultToBranchedActionIdsMap(mappedImportableResourcesDTO - .getActionResultDTO() - .getPublishedCollectionIdToActionIdsMap() - .get(idFromJsonFile)); publishedCollection.setPluginId( mappedImportableResourcesDTO.getPluginMap().get(publishedCollection.getPluginId())); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/refactors/ActionCollectionRefactoringServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/refactors/ActionCollectionRefactoringServiceCEImpl.java index 3bbafde616..55338f5604 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/refactors/ActionCollectionRefactoringServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/refactors/ActionCollectionRefactoringServiceCEImpl.java @@ -21,7 +21,6 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -119,17 +118,10 @@ public class ActionCollectionRefactoringServiceCEImpl implements EntityRefactori return branchedActionCollectionDTOMono .flatMap(branchedActionCollection -> { - final HashMap actionIds = new HashMap<>(); - if (branchedActionCollection.getDefaultToBranchedActionIdsMap() != null) { - actionIds.putAll(branchedActionCollection.getDefaultToBranchedActionIdsMap()); - } - if (branchedActionCollection.getDefaultToBranchedArchivedActionIdsMap() != null) { - actionIds.putAll(branchedActionCollection.getDefaultToBranchedArchivedActionIdsMap()); - } - - Flux actionUpdatesFlux = Flux.fromIterable(actionIds.values()) - .flatMap(actionId -> newActionService.findActionDTObyIdAndViewMode( - actionId, false, actionPermission.getEditPermission())) + Flux actionUpdatesFlux = newActionService + .findByCollectionIdAndViewMode( + branchedActionCollection.getId(), false, actionPermission.getEditPermission()) + .map(action -> newActionService.generateActionByViewMode(action, false)) .flatMap(actionDTO -> { actionDTO.setFullyQualifiedName(newName + "." + actionDTO.getName()); return newActionService diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/clonepage/ClonePageServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/clonepage/ClonePageServiceCE.java index 6f885c91bd..8dd65b3b68 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/clonepage/ClonePageServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/clonepage/ClonePageServiceCE.java @@ -6,6 +6,4 @@ import reactor.core.publisher.Mono; public interface ClonePageServiceCE { Mono cloneEntities(ClonePageMetaDTO clonePageMetaDTO); - - Mono updateClonedEntities(ClonePageMetaDTO clonePageMetaDTO); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/NewActionCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/NewActionCE.java index 815ac4b2fb..8751c3c335 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/NewActionCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/NewActionCE.java @@ -78,8 +78,15 @@ public class NewActionCE extends BranchAwareDomain { public static final String unpublishedAction_actionConfiguration_httpMethod = dotted(unpublishedAction, ActionDTO.Fields.actionConfiguration, ActionConfiguration.Fields.httpMethod); + public static final String publishedAction_datasource_id = + dotted(publishedAction, ActionDTO.Fields.datasource, Datasource.Fields.id); public static final String publishedAction_name = dotted(publishedAction, ActionDTO.Fields.name); public static final String publishedAction_pageId = dotted(publishedAction, ActionDTO.Fields.pageId); public static final String publishedAction_contextType = dotted(publishedAction, ActionDTO.Fields.contextType); + + public static final String unpublishedAction_collectionId = + dotted(unpublishedAction, ActionDTO.Fields.collectionId); + public static final String publishedAction_collectionId = + dotted(publishedAction, ActionDTO.Fields.collectionId); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ClonePageMetaDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ClonePageMetaDTO.java index aa1a3020e2..b8d37d15e8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ClonePageMetaDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ClonePageMetaDTO.java @@ -1,14 +1,11 @@ package com.appsmith.server.dtos; -import com.appsmith.server.domains.ActionCollection; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; @Data @@ -19,6 +16,5 @@ public class ClonePageMetaDTO { String branchedSourcePageId; PageDTO clonedPageDTO; String branchName; - Map oldToNewActionIdMap = new HashMap<>(); - List clonedActionCollections = new ArrayList<>(); + Map oldToNewCollectionIds = new HashMap<>(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionCE_DTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionCE_DTO.java index 0c4f3667ea..612ffd083c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionCE_DTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionCE_DTO.java @@ -24,7 +24,6 @@ import org.springframework.data.annotation.Transient; import java.time.Instant; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNewFieldValuesIntoOldObject; @@ -74,32 +73,12 @@ public class ActionCollectionCE_DTO { @JsonView(Views.Public.class) Instant deletedAt; - // This property is not shared with the client since the reference is only useful to server - // Map - @JsonView(Views.Internal.class) - Map defaultToBranchedActionIdsMap = Map.of(); - - @Deprecated - @JsonView(Views.Public.class) - Set actionIds = Set.of(); - - // This property is not shared with the client since the reference is only useful to server - // Archived actions represent actions that have been removed from a js object but may be subject to re-use by the - // user - // Map - @JsonView(Views.Internal.class) - Map defaultToBranchedArchivedActionIdsMap = Map.of(); - - @Deprecated - @JsonView(Views.Public.class) - Set archivedActionIds = Set.of(); - // Instead of storing the entire action object, we only populate this field while interacting with the client side @Transient @JsonView(Views.Public.class) List actions = List.of(); - // Instead of storing the entire action object, we only populate this field while interacting with the client side + // TODO : Remove after clean up, this is only kept as of now because removing it will show up as a diff on git @Transient @JsonView(Views.Public.class) List archivedActions = List.of(); @@ -152,10 +131,6 @@ public class ActionCollectionCE_DTO { public void sanitiseForExport() { this.resetTransientFields(); this.setDefaultResources(null); - this.setDefaultToBranchedActionIdsMap(null); - this.setDefaultToBranchedArchivedActionIdsMap(null); - this.setActionIds(null); - this.setArchivedActionIds(null); this.setUserPermissions(Set.of()); } @@ -170,7 +145,6 @@ public class ActionCollectionCE_DTO { this.setApplicationId(null); this.setErrorReports(null); this.setActions(List.of()); - this.setArchivedActions(List.of()); } public String calculateContextId() { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCEImpl.java index f45f07f8b5..d0609b41bb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCEImpl.java @@ -2,7 +2,6 @@ package com.appsmith.server.fork.internal; import com.appsmith.external.constants.ActionCreationSourceTypeEnum; import com.appsmith.external.constants.AnalyticsEvents; -import com.appsmith.external.dtos.DslExecutableDTO; import com.appsmith.external.helpers.AppsmithEventContext; import com.appsmith.external.helpers.AppsmithEventContextType; import com.appsmith.external.models.ActionDTO; @@ -33,6 +32,7 @@ import com.appsmith.server.fork.forkable.ForkableService; import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.helpers.UserPermissionUtils; import com.appsmith.server.imports.internal.ImportService; +import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.repositories.NewActionRepository; @@ -55,6 +55,7 @@ import org.apache.commons.lang.StringUtils; import org.bson.types.ObjectId; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.util.function.Tuple2; import java.util.ArrayList; import java.util.HashMap; @@ -90,6 +91,7 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic private final NewActionRepository newActionRepository; private final WorkspaceRepository workspaceRepository; private final ForkableService datasourceForkableService; + private final UpdateLayoutService updateLayoutService; /** * Clone all applications (except deleted ones), including its pages and actions from one workspace into * another. Also clones all datasources (not just the ones used by any applications) provided in the parameter list. @@ -178,219 +180,174 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic .forkWithConfiguration(forkWithConfig) .build(); - return applicationPageService + Mono createForkedPageMono = applicationPageService .createPage(page) .flatMap(savedPage -> isDefault ? applicationPageService .makePageDefault(savedPage) .thenReturn(savedPage) : Mono.just(savedPage)) - .flatMap(savedPage -> newPageRepository.findById(savedPage.getId())) - .flatMap(savedPage -> { - clonedPages.add(savedPage); - Flux sourceActionFlux = newActionService - .findByPageId(templatePageId) - .cache(); + .flatMap(savedPage -> newPageRepository.findById(savedPage.getId())); - forkingSourceToForkableActionsFluxMap.put(sourceMetaForPage, sourceActionFlux); + return createForkedPageMono.flatMap(savedPage -> { + clonedPages.add(savedPage); + Flux sourceActionFlux = newActionService + .findByPageIdsForExport(List.of(templatePageId), Optional.empty()) + .cache(); - ForkingMetaDTO targetMetaForPage = targetMeta.toBuilder() - .applicationId(newPage.getApplicationId()) - .pageId(newPage.getId()) - .forkWithConfiguration(forkWithConfig) - .build(); + forkingSourceToForkableActionsFluxMap.put(sourceMetaForPage, sourceActionFlux); - Flux forkableDatasourceFlux = datasourceForkableService - .getForkableEntitiesFromSource(sourceMetaForPage, sourceActionFlux) - .map(forkableDatasource -> { - if (!clonedDatasourceMonos.containsKey(forkableDatasource.getId())) { - Mono datasourceMono = datasourceForkableService - .createForkedEntity( - forkableDatasource, - sourceMetaForPage, - targetMetaForPage, - existingDatasourcesMono) - .cache(); - clonedDatasourceMonos.put(forkableDatasource.getId(), datasourceMono); - } - return forkableDatasource; - }); + ForkingMetaDTO targetMetaForPage = targetMeta.toBuilder() + .applicationId(newPage.getApplicationId()) + .pageId(newPage.getId()) + .forkWithConfiguration(forkWithConfig) + .build(); - return forkableDatasourceFlux - .thenMany(sourceActionFlux) - .map(newAction -> { - ActionDTO action = newAction.getUnpublishedAction(); - log.info( - "Preparing action for cloning {} {}.", - action.getName(), - newAction.getId()); - action.setPageId(savedPage.getId()); - action.setDefaultResources(null); - return newAction; - }) - .flatMap(newAction -> { - final String originalActionId = newAction.getId(); - log.info("Creating clone of action {}", originalActionId); - newAction.makePristine(); - newAction.setWorkspaceId(toWorkspaceId); - ActionDTO action = newAction.getUnpublishedAction(); - action.setCollectionId(null); + Flux forkableDatasourceFlux = datasourceForkableService + .getForkableEntitiesFromSource(sourceMetaForPage, sourceActionFlux) + .map(forkableDatasource -> { + if (!clonedDatasourceMonos.containsKey(forkableDatasource.getId())) { + Mono datasourceMono = datasourceForkableService + .createForkedEntity( + forkableDatasource, + sourceMetaForPage, + targetMetaForPage, + existingDatasourcesMono) + .cache(); + clonedDatasourceMonos.put(forkableDatasource.getId(), datasourceMono); + } + return forkableDatasource; + }); - Mono actionMono = Mono.just(action); - final Datasource datasourceInsideAction = action.getDatasource(); - if (datasourceInsideAction != null) { - if (datasourceInsideAction.getId() != null) { - final String datasourceId = datasourceInsideAction.getId(); - actionMono = clonedDatasourceMonos - .get(datasourceId) - .map(newDatasource -> { - action.setDatasource(newDatasource); - return action; - }); - } else { - // If this is an embedded datasource, the config will get forked - // along with the action - datasourceInsideAction.setWorkspaceId(toWorkspaceId); + Mono> forkedCollectionsMono = actionCollectionService + .findByPageId(templatePageId) + .flatMap(actionCollection -> { + // Keep a record of the original collection id + final String originalCollectionId = actionCollection.getId(); + log.info("Creating clone of action collection {}", originalCollectionId); + // Sanitize them + actionCollection.makePristine(); + actionCollection.setPublishedCollection(null); + final ActionCollectionDTO unpublishedCollection = + actionCollection.getUnpublishedCollection(); + unpublishedCollection.setPageId(savedPage.getId()); + + DefaultResources defaultResources = new DefaultResources(); + defaultResources.setPageId(savedPage.getId()); + unpublishedCollection.setDefaultResources(defaultResources); + + actionCollection.setWorkspaceId(toWorkspaceId); + actionCollection.setApplicationId(savedPage.getApplicationId()); + + DefaultResources defaultResources1 = new DefaultResources(); + defaultResources1.setApplicationId(savedPage.getApplicationId()); + actionCollection.setDefaultResources(defaultResources1); + + actionCollectionService.generateAndSetPolicies(savedPage, actionCollection); + + return actionCollectionService + .create(actionCollection) + .flatMap(clonedActionCollection -> { + Mono> tuple2Mono = Mono.zip( + Mono.just(clonedActionCollection.getId()), + Mono.just(originalCollectionId)); + + if (org.springframework.util.StringUtils.isEmpty(clonedActionCollection + .getDefaultResources() + .getCollectionId())) { + ActionCollection updates = new ActionCollection(); + DefaultResources defaultResources2 = + clonedActionCollection.getDefaultResources(); + defaultResources2.setCollectionId(clonedActionCollection.getId()); + updates.setDefaultResources(defaultResources2); + return actionCollectionService + .update(clonedActionCollection.getId(), updates) + .then(tuple2Mono); } - } - return Mono.zip( - actionMono - .flatMap(actionDTO -> { - // Indicates that source of action creation is fork - // application - actionDTO.setSource( - ActionCreationSourceTypeEnum.FORK_APPLICATION); - return layoutActionService.createAction( - actionDTO, - new AppsmithEventContext( - AppsmithEventContextType.CLONE_PAGE), - Boolean.FALSE); - }) - .map(ActionDTO::getId), - Mono.justOrEmpty(originalActionId)); - }) - // This call to `collectMap` will wait for all actions in all pages to have been - // processed, and so the - // `clonedPages` list will also contain all pages cloned. - .collect( - HashMap::new, - (map, tuple2) -> map.put(tuple2.getT2(), tuple2.getT1())) - .flatMap(actionIdsMap -> { - // Map of - HashMap collectionIdsMap = new HashMap<>(); - // Pick all action collections - return actionCollectionService - .findByPageId(templatePageId) - .flatMap(actionCollection -> { - // Keep a record of the original collection id - final String originalCollectionId = actionCollection.getId(); - log.info( - "Creating clone of action collection {}", - originalCollectionId); - // Sanitize them - actionCollection.makePristine(); - actionCollection.setPublishedCollection(null); - final ActionCollectionDTO unpublishedCollection = - actionCollection.getUnpublishedCollection(); - unpublishedCollection.setPageId(savedPage.getId()); + return tuple2Mono; + }); + }) + .collect( + HashMap::new, + (map, tuple2) -> map.put(tuple2.getT2(), tuple2.getT1())) + .cache(); - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setPageId(savedPage.getId()); - unpublishedCollection.setDefaultResources(defaultResources); + Mono> forkedActionsMono = + forkedCollectionsMono.flatMap(collectionIdMap -> { + return sourceActionFlux + .map(newAction -> { + ActionDTO action = newAction.getUnpublishedAction(); + log.info( + "Preparing action for cloning {} {}.", + action.getName(), + newAction.getId()); + action.setPageId(savedPage.getId()); + action.setDefaultResources(null); + return newAction; + }) + .flatMap(newAction -> { + final String originalActionId = newAction.getId(); + String originalCollectionId = newAction + .getUnpublishedAction() + .getCollectionId(); + String forkedCollectionId = collectionIdMap.get(originalCollectionId); + log.info("Creating clone of action {}", originalActionId); + newAction.makePristine(); + newAction.setWorkspaceId(toWorkspaceId); + ActionDTO action = newAction.getUnpublishedAction(); + action.setCollectionId(forkedCollectionId); - actionCollection.setWorkspaceId(toWorkspaceId); - actionCollection.setApplicationId(savedPage.getApplicationId()); - - DefaultResources defaultResources1 = new DefaultResources(); - defaultResources1.setApplicationId( - savedPage.getApplicationId()); - actionCollection.setDefaultResources(defaultResources1); - - actionCollectionService.generateAndSetPolicies( - savedPage, actionCollection); - - // Replace all action Ids from map and replace with newly - // created actionIds - final Map newActionIds = new HashMap<>(); - unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .forEach((defaultActionId, oldActionId) -> { - if (org.springframework.util.StringUtils.hasLength( - oldActionId) - && org.springframework.util.StringUtils - .hasLength(actionIdsMap.get( - oldActionId))) { - - // As this is a new application and not - // connected - // through git branch, the default and newly - // created actionId will be same - newActionIds.put( - actionIdsMap.get(oldActionId), - actionIdsMap.get(oldActionId)); - } else { - log.debug( - "Unable to find action {} while forking inside ID map: {}", - oldActionId, - actionIdsMap); - } + Mono actionMono = Mono.just(action); + final Datasource datasourceInsideAction = action.getDatasource(); + if (datasourceInsideAction != null) { + if (datasourceInsideAction.getId() != null) { + final String datasourceId = datasourceInsideAction.getId(); + actionMono = clonedDatasourceMonos + .get(datasourceId) + .map(newDatasource -> { + action.setDatasource(newDatasource); + return action; }); - - unpublishedCollection.setDefaultToBranchedActionIdsMap( - newActionIds); - - return actionCollectionService - .create(actionCollection) - .flatMap(clonedActionCollection -> { - if (org.springframework.util.StringUtils.isEmpty( - clonedActionCollection - .getDefaultResources() - .getCollectionId())) { - ActionCollection updates = - new ActionCollection(); - DefaultResources defaultResources2 = - clonedActionCollection - .getDefaultResources(); - defaultResources2.setCollectionId( - clonedActionCollection.getId()); - updates.setDefaultResources(defaultResources2); - return actionCollectionService.update( - clonedActionCollection.getId(), - updates); - } - return Mono.just(clonedActionCollection); + } else { + // If this is an embedded datasource, the config will get forked + // along with the action + datasourceInsideAction.setWorkspaceId(toWorkspaceId); + } + } + return Mono.zip( + actionMono + .flatMap(actionDTO -> { + actionDTO.setId(null); + // Indicates that source of action creation is fork + // application + actionDTO.setSource( + ActionCreationSourceTypeEnum + .FORK_APPLICATION); + return layoutActionService.createAction( + actionDTO, + new AppsmithEventContext( + AppsmithEventContextType + .CLONE_PAGE), + Boolean.FALSE); }) - .flatMap(clonedActionCollection -> { - collectionIdsMap.put( - originalCollectionId, - clonedActionCollection.getId()); - return Flux.fromIterable(newActionIds.values()) - .flatMap(newActionService::findById) - .flatMap(newlyCreatedAction -> { - ActionDTO unpublishedAction = - newlyCreatedAction - .getUnpublishedAction(); - unpublishedAction.setCollectionId( - clonedActionCollection.getId()); - unpublishedAction - .getDefaultResources() - .setCollectionId( - clonedActionCollection - .getId()); - return newActionService.update( - newlyCreatedAction.getId(), - newlyCreatedAction); - }) - .collectList(); - }); - }) - .collectList() - .then(Mono.zip( - Mono.just(actionIdsMap), Mono.just(collectionIdsMap))); - }); - }); + .map(ActionDTO::getId), + Mono.justOrEmpty(originalActionId)); + }) + // This call to `collectMap` will wait for all actions in all pages to have + // been processed, + // and so the `clonedPages` list will also contain all pages cloned. + .collect( + HashMap::new, + (map, tuple2) -> map.put(tuple2.getT2(), tuple2.getT1())); + }); + + return forkableDatasourceFlux + .then(forkedCollectionsMono) + .zipWhen(forkedCollectionsMap -> forkedActionsMono); + }); }) - .flatMap(tuple -> updateActionAndCollectionsIdsInForkedPages(clonedPages, tuple.getT1(), tuple.getT2())) + .flatMapIterable(tuple2 -> clonedPages) + .flatMap(clonedPage -> updateLayoutService.updatePageLayoutsByPageId(clonedPage.getId())) // Now publish all the example applications which have been cloned to ensure that there is a // view mode for the newly created user. .then(Mono.just(newApplicationIds)) @@ -399,63 +356,6 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic .collectList(); } - private Flux updateActionAndCollectionsIdsInForkedPages( - List clonedPages, Map actionIdsMap, Map actionCollectionIdsMap) { - final List> pageSaveMonos = new ArrayList<>(); - - for (final NewPage page : clonedPages) { - // If there are no unpublished layouts, there would be no published layouts either. - // Move on to the next page. - if (page.getUnpublishedPage().getLayouts() == null) { - continue; - } - - boolean shouldSave = false; - - for (final Layout layout : page.getUnpublishedPage().getLayouts()) { - if (layout.getLayoutOnLoadActions() != null) { - shouldSave = updateOnLoadActionsWithNewActionAndCollectionIds( - actionIdsMap, actionCollectionIdsMap, page.getId(), shouldSave, layout); - } - } - - if (shouldSave) { - pageSaveMonos.add(newPageRepository.save(page)); - } - } - - return Flux.concat(pageSaveMonos); - } - - private boolean updateOnLoadActionsWithNewActionAndCollectionIds( - Map actionIdsMap, - Map collectionIdsMap, - String pageId, - boolean shouldSave, - Layout layout) { - for (final Set actionSet : layout.getLayoutOnLoadActions()) { - for (final DslExecutableDTO actionDTO : actionSet) { - if (actionIdsMap.containsKey(actionDTO.getId())) { - final String srcActionId = actionDTO.getId(); - final String srcCollectionId = actionDTO.getCollectionId(); - actionDTO.setId(actionIdsMap.get(srcActionId)); - actionDTO.setDefaultActionId(actionIdsMap.get(srcActionId)); - if (org.springframework.util.StringUtils.hasLength(srcCollectionId)) { - actionDTO.setDefaultCollectionId(collectionIdsMap.get(actionDTO.getCollectionId())); - actionDTO.setCollectionId(collectionIdsMap.get(actionDTO.getCollectionId())); - } - shouldSave = true; - } else { - log.error( - "Couldn't find cloned action ID for publishedLayoutOnLoadAction {} in page {}", - actionDTO.getId(), - pageId); - } - } - } - return shouldSave; - } - /** * This function simply creates a clone of the Application object without cloning its children (page and actions) * Once the new application object is created, it adds the new application's id into the list applicationIds diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceImpl.java index c09e07063a..019687dcd7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceImpl.java @@ -6,6 +6,7 @@ import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.fork.forkable.ForkableService; import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.imports.internal.ImportService; +import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.repositories.NewActionRepository; @@ -51,7 +52,8 @@ public class ApplicationForkingServiceImpl extends ApplicationForkingServiceCEIm ActionCollectionRepository actionCollectionRepository, NewActionRepository newActionRepository, WorkspaceRepository workspaceRepository, - ForkableService datasourceForkableService) { + ForkableService datasourceForkableService, + UpdateLayoutService updateLayoutService) { super( applicationService, workspaceService, @@ -73,6 +75,7 @@ public class ApplicationForkingServiceImpl extends ApplicationForkingServiceCEIm actionCollectionRepository, newActionRepository, workspaceRepository, - datasourceForkableService); + datasourceForkableService, + updateLayoutService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/DefaultResourcesUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/DefaultResourcesUtils.java index 83ce5e03f4..1731af079e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/DefaultResourcesUtils.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/DefaultResourcesUtils.java @@ -10,8 +10,6 @@ import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.dtos.PageDTO; import org.apache.commons.lang3.StringUtils; -import java.util.HashMap; -import java.util.Map; import java.util.Optional; import java.util.Set; @@ -134,16 +132,6 @@ public class DefaultResourcesUtils { collectionDTODefaultResources.setBranchName(null); collectionDTODefaultResources.setCollectionId(null); - if (updateActionIds) { - Map updatedActionIds = new HashMap<>(); - if (!CollectionUtils.isNullOrEmpty(collectionDTO.getDefaultToBranchedActionIdsMap())) { - collectionDTO - .getDefaultToBranchedActionIdsMap() - .values() - .forEach(val -> updatedActionIds.put(val, val)); - collectionDTO.setDefaultToBranchedActionIdsMap(updatedActionIds); - } - } collectionDTO.setDefaultResources(collectionDTODefaultResources); } return resource; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ResponseUtilsCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ResponseUtilsCE.java index 7fe4a2e23d..ac965ed404 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ResponseUtilsCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ResponseUtilsCE.java @@ -265,10 +265,6 @@ public class ResponseUtilsCE { actionDto.setCollectionId(defaultResourceIds.getCollectionId()); this.updateActionDTOWithDefaultResources(actionDto); }); - collection.getArchivedActions().forEach(actionDto -> { - actionDto.setCollectionId(defaultResourceIds.getCollectionId()); - this.updateActionDTOWithDefaultResources(actionDto); - }); return collection; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCE.java index 16a4e30d75..55bd6bde08 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCE.java @@ -96,6 +96,8 @@ public interface NewActionServiceCE extends CrudService { Flux getUnpublishedActions(MultiValueMap params, String branchName); + Mono deleteGivenNewAction(NewAction toDelete); + Mono populateHintMessages(ActionDTO action); Mono save(NewAction action); @@ -104,6 +106,8 @@ public interface NewActionServiceCE extends CrudService { Flux findByPageId(String pageId); + Mono archiveGivenNewAction(NewAction toDelete); + Mono archive(NewAction newAction); Mono archiveById(String id); @@ -160,4 +164,6 @@ public interface NewActionServiceCE extends CrudService { void updateDefaultResourcesInAction(NewAction newAction); Mono saveLastEditInformationInParent(ActionDTO actionDTO); + + Flux findByCollectionIdAndViewMode(String collectionId, boolean viewMode, AclPermission aclPermission); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java index 714da0b1eb..3673af492f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java @@ -858,80 +858,49 @@ public class NewActionServiceCEImpl extends BaseService { - Mono newActionMono; + return actionMono.flatMap(this::deleteGivenNewAction); + } - // Using the name field to determine if the action was ever published. In case of never published - // action, publishedAction would exist with empty datasource and default fields. - if (toDelete.getPublishedAction() != null - && toDelete.getPublishedAction().getName() != null) { - toDelete.getUnpublishedAction().setDeletedAt(Instant.now()); - newActionMono = repository - .save(toDelete) - .zipWith(Mono.defer(() -> { - final ActionDTO action = toDelete.getUnpublishedAction(); - if (action.getDatasource() != null - && action.getDatasource().getId() != null) { - return datasourceService.findById( - action.getDatasource().getId()); - } else { - return Mono.justOrEmpty(action.getDatasource()); - } - })) - .flatMap(zippedActions -> { - final Datasource datasource = zippedActions.getT2(); - final NewAction newAction1 = zippedActions.getT1(); - final Map data = - this.getAnalyticsProperties(newAction1, datasource); - final Map eventData = Map.of( - FieldName.APP_MODE, - ApplicationMode.EDIT.toString(), - FieldName.ACTION, - newAction1); - data.put(FieldName.EVENT_DATA, eventData); + @Override + public Mono deleteGivenNewAction(NewAction toDelete) { + Mono newActionMono; - return analyticsService - .sendArchiveEvent(newAction1, data) - .thenReturn(zippedActions.getT1()); - }) - .thenReturn(toDelete); - } else { - // This action was never published. This document can be safely archived - newActionMono = repository - .archive(toDelete) - .zipWith(Mono.defer(() -> { - final ActionDTO action = toDelete.getUnpublishedAction(); - if (action.getDatasource() != null - && action.getDatasource().getId() != null) { - return datasourceService.findById( - action.getDatasource().getId()); - } else { - return Mono.justOrEmpty(action.getDatasource()); - } - })) - .flatMap(zippedActions -> { - final Datasource datasource = zippedActions.getT2(); - final NewAction newAction1 = zippedActions.getT1(); - final Map data = - this.getAnalyticsProperties(newAction1, datasource); - final Map eventData = Map.of( - FieldName.APP_MODE, - ApplicationMode.EDIT.toString(), - FieldName.ACTION, - newAction1); - data.put(FieldName.EVENT_DATA, eventData); + // Using the name field to determine if the action was ever published. In case of never published + // action, publishedAction would exist with empty datasource and default fields. + if (toDelete.getPublishedAction() != null + && toDelete.getPublishedAction().getName() != null) { + toDelete.getUnpublishedAction().setDeletedAt(Instant.now()); + newActionMono = repository + .save(toDelete) + .zipWith(Mono.defer(() -> { + final ActionDTO action = toDelete.getUnpublishedAction(); + if (action.getDatasource() != null + && action.getDatasource().getId() != null) { + return datasourceService.findById( + action.getDatasource().getId()); + } else { + return Mono.justOrEmpty(action.getDatasource()); + } + })) + .flatMap(zippedActions -> { + final Datasource datasource = zippedActions.getT2(); + final NewAction newAction1 = zippedActions.getT1(); + final Map data = this.getAnalyticsProperties(newAction1, datasource); + final Map eventData = Map.of( + FieldName.APP_MODE, ApplicationMode.EDIT.toString(), FieldName.ACTION, newAction1); + data.put(FieldName.EVENT_DATA, eventData); - return analyticsService - .sendDeleteEvent(newAction1, data) - .thenReturn(zippedActions.getT1()); - }) - .thenReturn(toDelete); - } + return analyticsService + .sendArchiveEvent(newAction1, data) + .thenReturn(zippedActions.getT1()); + }) + .thenReturn(toDelete); + } else { + // This action was never published. This document can be safely archived + newActionMono = archiveGivenNewAction(toDelete); + } - return newActionMono; - }) - .map(updatedAction -> generateActionByViewMode(updatedAction, false)); + return newActionMono.map(updatedAction -> generateActionByViewMode(updatedAction, false)); } /* @@ -1459,7 +1428,12 @@ public class NewActionServiceCEImpl extends BaseService repository + return actionMono.flatMap(this::archiveGivenNewAction); + } + + @Override + public Mono archiveGivenNewAction(NewAction toDelete) { + return repository .archive(toDelete) .zipWith(Mono.defer(() -> { final ActionDTO action = toDelete.getUnpublishedAction(); @@ -1479,7 +1453,7 @@ public class NewActionServiceCEImpl extends BaseService findByCollectionIdAndViewMode( + String collectionId, boolean viewMode, AclPermission aclPermission) { + return repository.findAllByCollectionIds(List.of(collectionId), viewMode, aclPermission); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/clonepage/ActionClonePageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/clonepage/ActionClonePageServiceCEImpl.java index 787f58f49b..3badc59c7f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/clonepage/ActionClonePageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/clonepage/ActionClonePageServiceCEImpl.java @@ -8,8 +8,6 @@ import com.appsmith.external.models.DefaultResources; import com.appsmith.server.clonepage.ClonePageServiceCE; import com.appsmith.server.domains.NewAction; import com.appsmith.server.dtos.ClonePageMetaDTO; -import com.appsmith.server.exceptions.AppsmithError; -import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.services.LayoutActionService; import com.appsmith.server.solutions.ActionPermission; @@ -18,8 +16,6 @@ import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.HashMap; - import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties; @Service @@ -33,13 +29,23 @@ public class ActionClonePageServiceCEImpl implements ClonePageServiceCE cloneEntities(ClonePageMetaDTO clonePageMetaDTO) { return getCloneableActions(clonePageMetaDTO.getBranchedSourcePageId()) .flatMap(action -> { - String originalActionId = action.getId(); // Set new page id in the actionDTO final DefaultResources clonedPageDefaultResources = clonePageMetaDTO.getClonedPageDTO().getDefaultResources(); - action.getUnpublishedAction() - .setPageId(clonePageMetaDTO.getClonedPageDTO().getId()); - action.getUnpublishedAction().setDefaultResources(clonedPageDefaultResources); + ActionDTO actionDTO = action.getUnpublishedAction(); + DefaultResources defaultResources = new DefaultResources(); + defaultResources.setPageId(clonedPageDefaultResources.getPageId()); + defaultResources.setBranchName(clonedPageDefaultResources.getBranchName()); + defaultResources.setApplicationId(clonedPageDefaultResources.getApplicationId()); + actionDTO.setDefaultResources(defaultResources); + + actionDTO.setPageId(clonePageMetaDTO.getClonedPageDTO().getId()); + if (actionDTO.getCollectionId() != null) { + String clonedActionCollectionId = + clonePageMetaDTO.getOldToNewCollectionIds().get(actionDTO.getCollectionId()); + actionDTO.setCollectionId(clonedActionCollectionId); + actionDTO.getDefaultResources().setCollectionId(clonedActionCollectionId); + } /* * - Now create the new action from the template of the source action. * - Use CLONE_PAGE context to make sure that page / application clone quirks are @@ -51,42 +57,16 @@ public class ActionClonePageServiceCEImpl implements ClonePageServiceCE { - clonePageMetaDTO - .getOldToNewActionIdMap() - .put(action.getId(), clonedAction.getId()); - return clonedAction.getId(); - }), - Mono.justOrEmpty(originalActionId)); + copyNestedNonNullProperties(actionDTO, cloneActionDTO); + return layoutActionService.createAction(cloneActionDTO, eventContext, Boolean.FALSE); }) - .collect(HashMap::new, (map, tuple2) -> map.put(tuple2.getT2(), tuple2.getT1())) - .flatMap(oldToClonedActionIdMap -> { - clonePageMetaDTO.setOldToNewActionIdMap(oldToClonedActionIdMap); - return Mono.empty().then(); - }); - } - - @Override - public Mono updateClonedEntities(ClonePageMetaDTO clonePageMetaDTO) { - return Mono.error(new AppsmithException(AppsmithError.UNSUPPORTED_OPERATION)); + .then(); } protected Flux getCloneableActions(String pageId) { - Flux sourceActionFlux = newActionService + return newActionService .findByPageId(pageId, actionPermission.getEditPermission()) - // Set collection reference in actions to null to reset to the new application's collections later - .map(newAction -> { - if (newAction.getUnpublishedAction() != null) { - newAction.getUnpublishedAction().setCollectionId(null); - } - return newAction; - }) // In case there are no actions in the page being cloned, return empty .switchIfEmpty(Flux.empty()); - return sourceActionFlux; } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/JsActionRefactoringServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/JsActionRefactoringServiceCEImpl.java index 54141556a9..295dc2e794 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/JsActionRefactoringServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/JsActionRefactoringServiceCEImpl.java @@ -84,10 +84,6 @@ public class JsActionRefactoringServiceCEImpl implements EntityRefactoringServic actionCollectionDTO.setName( dbActionCollection.getUnpublishedCollection().getName()); - actionCollectionDTO.setDefaultToBranchedActionIdsMap( - dbActionCollection.getUnpublishedCollection().getDefaultToBranchedActionIdsMap()); - actionCollectionDTO.setDefaultToBranchedArchivedActionIdsMap( - dbActionCollection.getUnpublishedCollection().getDefaultToBranchedArchivedActionIdsMap()); copyNewFieldValuesIntoOldObject(actionCollectionDTO, dbActionCollection.getUnpublishedCollection()); // First perform refactor of the action itself diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCE.java index b111d8b0e4..ea4e8221ec 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCE.java @@ -67,6 +67,8 @@ public interface CustomNewActionRepositoryCE extends AppsmithRepository findAllByApplicationIdsWithoutPermission(List applicationIds, List includeFields); + Flux findAllByCollectionIds(List collectionIds, boolean viewMode, AclPermission aclPermission); + Flux findAllUnpublishedActionsByContextIdAndContextType( String contextId, CreatorContextType contextType, AclPermission permission, boolean includeJs); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCEImpl.java index 8c5c1d3685..c1a8957b39 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCEImpl.java @@ -404,6 +404,19 @@ public class CustomNewActionRepositoryCEImpl extends BaseAppsmithRepositoryImpl< .all(); } + @Override + public Flux findAllByCollectionIds( + List collectionIds, boolean viewMode, AclPermission aclPermission) { + String collectionIdPath; + if (viewMode) { + collectionIdPath = NewAction.Fields.publishedAction_collectionId; + } else { + collectionIdPath = NewAction.Fields.unpublishedAction_collectionId; + } + BridgeQuery q = Bridge.in(collectionIdPath, collectionIds); + return queryBuilder().criteria(q).permission(aclPermission).all(); + } + @Override public Flux findAllUnpublishedActionsByContextIdAndContextType( String contextId, CreatorContextType contextType, AclPermission permission, boolean includeJs) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java index 0f2abfcc1c..7301bbce84 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java @@ -641,10 +641,6 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { return page; })); - final Flux sourceActionCollectionsFlux = getCloneableActionCollections(pageId); - - Flux sourceActionFlux = getCloneableActions(pageId); - return sourcePageMono .flatMap(page -> { clonePageMetaDTO.setBranchedSourcePageId(page.getId()); @@ -703,10 +699,9 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { } protected Mono clonePageDependentEntities(ClonePageMetaDTO clonePageMetaDTO) { - return actionClonePageService + return actionCollectionClonePageService .cloneEntities(clonePageMetaDTO) - .then(Mono.defer(() -> actionCollectionClonePageService.cloneEntities(clonePageMetaDTO))) - .then(Mono.defer(() -> actionCollectionClonePageService.updateClonedEntities(clonePageMetaDTO))); + .then(Mono.defer(() -> actionClonePageService.cloneEntities(clonePageMetaDTO))); } protected Mono updateClonedPageLayout(PageDTO savedPage) { @@ -1527,8 +1522,9 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { private Mono validateDatasourcesForCreatePermission(Mono applicationMono) { Flux datasourceFlux = applicationMono - .flatMapMany(application -> - newActionRepository.findIdAndDatasourceIdByApplicationIdIn(List.of(application.getId()))) + .flatMapMany(application -> newActionRepository.findAllByApplicationIdsWithoutPermission( + List.of(application.getId()), + List.of(NewAction.Fields.id, NewAction.Fields.unpublishedAction_datasource_id))) .collectList() .map(actions -> { return actions.stream() diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java index 8e35bf332f..d28feb39bf 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java @@ -30,8 +30,6 @@ import org.apache.commons.lang3.StringUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.time.Instant; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -201,17 +199,11 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE .flatMap(tuple -> { NewPage destinationPage = tuple.getT1(); ActionCollectionDTO actionCollectionDTO = tuple.getT2(); - final Map actionIds = new HashMap<>(); - if (actionCollectionDTO.getDefaultToBranchedActionIdsMap() != null) { - actionIds.putAll(actionCollectionDTO.getDefaultToBranchedActionIdsMap()); - } - if (actionCollectionDTO.getDefaultToBranchedArchivedActionIdsMap() != null) { - actionIds.putAll(actionCollectionDTO.getDefaultToBranchedArchivedActionIdsMap()); - } - final Flux actionUpdatesFlux = Flux.fromIterable(actionIds.values()) - .flatMap(actionId -> newActionService.findActionDTObyIdAndViewMode( - actionId, false, actionPermission.getEditPermission())) + final Flux actionUpdatesFlux = newActionService + .findByCollectionIdAndViewMode( + actionCollectionDTO.getId(), false, actionPermission.getEditPermission()) + .map(newAction -> newActionService.generateActionByViewMode(newAction, false)) .flatMap(actionDTO -> { actionDTO.setPageId(destinationPageId); // Update default page ID in actions as per destination page object @@ -336,13 +328,8 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE .map(ActionDTO::getId) .filter(Objects::nonNull) .collect(Collectors.toUnmodifiableSet()); - final Set archivedDefaultActionIds = actionCollectionDTO.getArchivedActions().stream() - .map(ActionDTO::getId) - .filter(Objects::nonNull) - .collect(Collectors.toUnmodifiableSet()); final Set defaultActionIds = new HashSet<>(); defaultActionIds.addAll(validDefaultActionIds); - defaultActionIds.addAll(archivedDefaultActionIds); final Mono> newValidActionIdsMono = branchedActionCollectionMono.flatMap( branchedActionCollection -> Flux.fromIterable(actionCollectionDTO.getActions()) @@ -393,102 +380,28 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE .collect(toMap( actionDTO -> actionDTO.getDefaultResources().getActionId(), ActionDTO::getId))); - final Mono> newArchivedActionIdsMono = branchedActionCollectionMono.flatMap( - branchedActionCollection -> Flux.fromIterable(actionCollectionDTO.getArchivedActions()) - .flatMap(actionDTO -> { - actionDTO.setCollectionId(branchedActionCollection.getId()); - actionDTO.setDeletedAt(Instant.now()); - setContextId(branchedActionCollection, actionDTO); - if (actionDTO.getId() == null) { - actionDTO.getDatasource().setWorkspaceId(actionCollectionDTO.getWorkspaceId()); - actionDTO.getDatasource().setPluginId(actionCollectionDTO.getPluginId()); - actionDTO.getDatasource().setName(FieldName.UNUSED_DATASOURCE); - actionDTO.setFullyQualifiedName( - actionCollectionDTO.getName() + "." + actionDTO.getName()); - actionDTO.setDefaultResources(branchedActionCollection.getDefaultResources()); - actionDTO.getDefaultResources().setBranchName(branchName); - final String defaultPageId = branchedActionCollection - .getUnpublishedCollection() - .getDefaultResources() - .getPageId(); - actionDTO.getDefaultResources().setPageId(defaultPageId); - // actionCollectionService is a new action, we need to create one - return layoutActionService - .createSingleAction(actionDTO, Boolean.TRUE) - // return an empty action so that the filter can remove it from the list - .onErrorResume(throwable -> { - log.debug( - "Failed to create action with name {} for collection: {}", - actionDTO.getName(), - actionCollectionDTO.getName()); - log.error(throwable.getMessage()); - return Mono.empty(); - }); - } else { - // Client only knows about the default action ID, fetch branched action id to update the - // action - Mono branchedActionIdMono = StringUtils.isEmpty(branchName) - ? Mono.just(actionDTO.getId()) - : newActionService - .findByBranchNameAndDefaultActionId( - branchName, - actionDTO.getId(), - false, - actionPermission.getEditPermission()) - .map(NewAction::getId); - actionDTO.setId(null); - return branchedActionIdMono.flatMap( - actionId -> layoutActionService.updateSingleAction(actionId, actionDTO)); - } - }) - .collect(toMap( - actionDTO -> actionDTO.getDefaultResources().getActionId(), ActionDTO::getId))); - // First collect all valid action ids from before, and diff against incoming action ids - return branchedActionCollectionMono - .map(branchedActionCollection -> { - // From the existing collection, if an action id is not referenced at all anymore, - // this means the action has been somehow deleted - final Set oldDefaultActionIds = new HashSet<>(); - if (branchedActionCollection.getUnpublishedCollection().getDefaultToBranchedActionIdsMap() - != null) { - oldDefaultActionIds.addAll(branchedActionCollection - .getUnpublishedCollection() - .getDefaultToBranchedActionIdsMap() - .keySet()); - } - if (branchedActionCollection.getUnpublishedCollection().getDefaultToBranchedArchivedActionIdsMap() - != null) { - oldDefaultActionIds.addAll(branchedActionCollection - .getUnpublishedCollection() - .getDefaultToBranchedArchivedActionIdsMap() - .keySet()); - } - - return oldDefaultActionIds.stream() - .filter(Objects::nonNull) - .filter(x -> !defaultActionIds.contains(x)) - .collect(Collectors.toUnmodifiableSet()); - }) - .flatMapMany(Flux::fromIterable) - .flatMap(defaultActionId -> newActionService - .findBranchedIdByBranchNameAndDefaultActionId( - branchName, defaultActionId, actionPermission.getEditPermission()) - .flatMap(newActionService::deleteUnpublishedAction) + Mono> deleteNonExistingActionMono = newActionService + .findByCollectionIdAndViewMode(actionCollectionDTO.getId(), false, actionPermission.getEditPermission()) + .filter(newAction -> !defaultActionIds.contains( + newAction.getDefaultResources().getActionId())) + .flatMap(x -> newActionService + .deleteGivenNewAction(x) // return an empty action so that the filter can remove it from the list .onErrorResume(throwable -> { log.debug( "Failed to delete action with id {}, branch {} for collection: {}", - defaultActionId, + x.getDefaultResources().getActionId(), branchName, actionCollectionDTO.getName()); log.error(throwable.getMessage()); return Mono.empty(); })) - .then(Mono.zip(newValidActionIdsMono, newArchivedActionIdsMono)) + .collectList(); + + return deleteNonExistingActionMono + .then(newValidActionIdsMono) .flatMap(tuple -> { - actionCollectionDTO.setDefaultToBranchedActionIdsMap(tuple.getT1()); - actionCollectionDTO.setDefaultToBranchedArchivedActionIdsMap(tuple.getT2()); return branchedActionCollectionMono.map(dbActionCollection -> { actionCollectionDTO.setId(null); resetContextId(actionCollectionDTO); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/GitServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/GitServiceCETest.java similarity index 99% rename from app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/GitServiceCETest.java rename to app/server/appsmith-server/src/test/java/com/appsmith/server/git/GitServiceCETest.java index ff75a0e4bf..c75fac1aea 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/GitServiceCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/GitServiceCETest.java @@ -1,4 +1,4 @@ -package com.appsmith.server.services.ce; +package com.appsmith.server.git; import com.appsmith.external.dtos.GitBranchDTO; import com.appsmith.external.dtos.GitStatusDTO; @@ -63,6 +63,7 @@ import com.appsmith.server.services.LayoutCollectionService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.UserService; import com.appsmith.server.services.WorkspaceService; +import com.appsmith.server.services.ce.GitServiceCE; import com.appsmith.server.solutions.ApplicationPermission; import com.appsmith.server.solutions.EnvironmentPermission; import com.appsmith.server.themes.base.ThemeService; @@ -1241,7 +1242,6 @@ public class GitServiceCETest { actionCollectionDTO.setActions(List.of(action1)); actionCollectionDTO.setPluginType(PluginType.JS); actionCollectionDTO.setDefaultResources(branchedResources); - actionCollectionDTO.setDefaultToBranchedActionIdsMap(Map.of("branchedId", "collectionId")); return Mono.zip( layoutActionService @@ -1329,16 +1329,6 @@ public class GitServiceCETest { ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap()) - .hasSize(1); - unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .keySet() - .forEach(key -> assertThat(key) - .isEqualTo(unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .get(key))); - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); assertThat(unpublishedCollection.getDefaultResources().getPageId()) .isEqualTo(application.getPages().get(0).getId()); @@ -2682,11 +2672,6 @@ public class GitServiceCETest { ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap()) - .hasSize(1); - unpublishedCollection.getDefaultToBranchedActionIdsMap().forEach((key, value) -> assertThat(key) - .isNotEqualTo(value)); - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); assertThat(unpublishedCollection.getDefaultResources().getPageId()) .isEqualTo(parentApplication.getPages().get(0).getId()); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java index 5f101b3807..0625256862 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java @@ -46,7 +46,6 @@ import reactor.test.StepVerifier; import java.util.ArrayList; import java.util.List; -import java.util.Map; import static com.appsmith.server.services.ce.ApplicationPageServiceCEImpl.EVALUATION_VERSION; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -270,7 +269,6 @@ class RefactoringServiceCEImplTest { oldActionCollection.setId("testCollectionId"); oldUnpublishedCollection.setPageId("testPageId"); oldUnpublishedCollection.setName("oldName"); - oldUnpublishedCollection.setDefaultToBranchedActionIdsMap(Map.of("defaultTestActionId", "testActionId")); oldActionCollection.setUnpublishedCollection(oldUnpublishedCollection); oldActionCollection.setDefaultResources(setDefaultResources(oldActionCollection)); oldUnpublishedCollection.setDefaultResources(setDefaultResources(oldUnpublishedCollection)); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCETest.java index 88e4f7cd66..b16cee0402 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCETest.java @@ -813,11 +813,9 @@ class RefactoringServiceCETest { assert createdActionCollectionDTO1 != null; final Mono actionCollectionMono = actionCollectionService.getById(createdActionCollectionDTO1.getId()); - final Optional optional = - createdActionCollectionDTO1.getDefaultToBranchedActionIdsMap().values().stream() - .findFirst(); - assert optional.isPresent(); - final Mono actionMono = newActionService.findById(optional.get()); + final Mono actionMono = newActionService + .findByCollectionIdAndViewMode(createdActionCollectionDTO1.getId(), false, null) + .next(); StepVerifier.create(Mono.zip(actionCollectionMono, actionMono)) .assertNext(tuple -> { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java index f256fab3da..6ded20d9b4 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java @@ -12,23 +12,17 @@ import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; import com.appsmith.server.defaultresources.DefaultResourcesService; import com.appsmith.server.domains.ActionCollection; -import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewAction; import com.appsmith.server.domains.NewPage; import com.appsmith.server.dtos.ActionCollectionDTO; -import com.appsmith.server.dtos.ActionCollectionMoveDTO; -import com.appsmith.server.dtos.LayoutDTO; -import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.ObjectMapperUtils; import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.refactors.applications.RefactoringService; import com.appsmith.server.repositories.ActionCollectionRepository; -import com.appsmith.server.repositories.ce.params.QueryAllParams; import com.appsmith.server.solutions.ActionPermission; import com.appsmith.server.solutions.ActionPermissionImpl; import com.appsmith.server.solutions.ApplicationPermission; @@ -39,7 +33,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.validation.Validator; import lombok.extern.slf4j.Slf4j; -import net.minidev.json.JSONObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -54,18 +47,14 @@ import reactor.test.StepVerifier; import java.io.File; import java.io.IOException; import java.time.Instant; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.doReturn; @ExtendWith(SpringExtension.class) @Slf4j @@ -477,6 +466,10 @@ public class ActionCollectionServiceImplTest { Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); + Mockito.when(newActionService.findByCollectionIdAndViewMode( + Mockito.anyString(), Mockito.anyBoolean(), Mockito.any())) + .thenReturn(Flux.empty()); + final Mono actionCollectionDTOMono = layoutCollectionService.updateUnpublishedActionCollection("testId", actionCollectionDTO, null); @@ -489,113 +482,6 @@ public class ActionCollectionServiceImplTest { .verify(); } - @Test - public void testUpdateUnpublishedActionCollection_withModifiedCollection_returnsValidCollection() - throws IOException { - ObjectMapper objectMapper = new ObjectMapper(); - ObjectMapperUtils objectMapperUtils = new ObjectMapperUtils(objectMapper); - - final JsonNode jsonNode = objectMapperUtils.readFromFile(mockObjects, Views.Public.class, JsonNode.class); - - String actionCollectionString = - objectMapperUtils.writeAsString(jsonNode.get("actionCollectionWithAction"), Views.Public.class); - final ActionCollection actionCollection = - objectMapperUtils.readFromString(actionCollectionString, Views.Public.class, ActionCollection.class); - - String actionCollectionDTOWithModifiedActionsString = objectMapperUtils.writeAsString( - jsonNode.get("actionCollectionDTOWithModifiedActions"), Views.Public.class); - final ActionCollectionDTO modifiedActionCollectionDTO = objectMapperUtils.readFromString( - actionCollectionDTOWithModifiedActionsString, Views.Public.class, ActionCollectionDTO.class); - - String actionCollectionAfterModifiedActionsString = objectMapperUtils.writeAsString( - jsonNode.get("actionCollectionAfterModifiedActions"), Views.Public.class); - final ActionCollection modifiedActionCollection = objectMapperUtils.readFromString( - actionCollectionAfterModifiedActionsString, Views.Public.class, ActionCollection.class); - - final ActionCollectionDTO unpublishedCollection = modifiedActionCollection.getUnpublishedCollection(); - unpublishedCollection.setDefaultToBranchedActionIdsMap( - Map.of("defaultTestActionId1", "testActionId1", "defaultTestActionId3", "testActionId3")); - unpublishedCollection.setDefaultToBranchedArchivedActionIdsMap(Map.of("defaultTestActionId2", "testActionId2")); - actionCollection.setDefaultResources(setDefaultResources(actionCollection)); - modifiedActionCollection.setDefaultResources(actionCollection.getDefaultResources()); - modifiedActionCollectionDTO.setDefaultResources(setDefaultResources(modifiedActionCollectionDTO)); - unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection)); - - final Instant archivedAfter = Instant.now(); - - Map updatedActions = new HashMap<>(); - Mockito.when(layoutActionService.updateSingleAction(Mockito.any(), Mockito.any())) - .thenAnswer(invocation -> { - final ActionDTO argument = (ActionDTO) invocation.getArguments()[1]; - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setActionId((String) invocation.getArguments()[0]); - argument.setDefaultResources(defaultResources); - argument.setId(defaultResources.getActionId()); - updatedActions.put(argument.getId(), argument); - return Mono.just(argument); - }); - - Mockito.when(newActionService.deleteUnpublishedAction(Mockito.any())).thenAnswer(invocation -> { - final ActionDTO argument = (ActionDTO) invocation.getArguments()[1]; - return Mono.just(argument); - }); - - final QueryAllParams params = Mockito.spy(new QueryAllParams<>(null)); - doReturn(Mono.just(1)).when(params).updateFirst(Mockito.any()); - Mockito.when(actionCollectionRepository.queryBuilder()).thenReturn(params); - - Mockito.when(actionCollectionRepository.findById(Mockito.anyString(), Mockito.any())) - .thenReturn(Mono.just(actionCollection)); - - Mockito.when(actionCollectionRepository.findById(Mockito.anyString())) - .thenReturn(Mono.just(modifiedActionCollection)); - - Mockito.when(newActionService.findActionDTObyIdAndViewMode(Mockito.any(), Mockito.any(), Mockito.any())) - .thenAnswer(invocation -> { - String id = (String) invocation.getArguments()[0]; - return Mono.just(updatedActions.get(id)); - }); - - Mockito.when(responseUtils.updateCollectionDTOWithDefaultResources(Mockito.any())) - .thenReturn(modifiedActionCollectionDTO); - - final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class); - - Mockito.when(newPageService.findByBranchNameAndDefaultPageId(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(Mono.just(newPage)); - - Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) - .thenReturn(Mono.just(newPage)); - - Mockito.when(actionCollectionRepository.setUserPermissionsInObject(Mockito.any())) - .thenReturn(Mono.just(modifiedActionCollection)); - - Mockito.when(updateLayoutService.updatePageLayoutsByPageId(Mockito.anyString())) - .thenAnswer(invocationOnMock -> { - return Mono.just(actionCollection.getUnpublishedCollection().getPageId()); - }); - - final Mono actionCollectionDTOMono = - layoutCollectionService.updateUnpublishedActionCollection( - "testCollectionId", modifiedActionCollectionDTO, null); - - StepVerifier.create(actionCollectionDTOMono) - .assertNext(actionCollectionDTO1 -> { - assertEquals(2, actionCollectionDTO1.getActions().size()); - assertEquals(1, actionCollectionDTO1.getArchivedActions().size()); - assertTrue(actionCollectionDTO1.getActions().stream() - .map(ActionDTO::getId) - .collect(Collectors.toSet()) - .containsAll(Set.of("testActionId1", "testActionId3"))); - assertEquals( - "testActionId2", - actionCollectionDTO1.getArchivedActions().get(0).getId()); - assertTrue(archivedAfter.isBefore( - actionCollectionDTO1.getArchivedActions().get(0).getDeletedAt())); - }) - .verifyComplete(); - } - @Test public void testDeleteUnpublishedActionCollection_withInvalidId_throwsError() { Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.>any())) @@ -631,6 +517,10 @@ public class ActionCollectionServiceImplTest { Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.>any())) .thenReturn(Mono.just(actionCollection)); + Mockito.when(newActionService.findByCollectionIdAndViewMode( + Mockito.anyString(), Mockito.anyBoolean(), Mockito.any())) + .thenReturn(Flux.empty()); + Mockito.when(actionCollectionRepository.save(Mockito.any())).thenAnswer(invocation -> { final ActionCollection argument = (ActionCollection) invocation.getArguments()[0]; return Mono.just(argument); @@ -662,8 +552,6 @@ public class ActionCollectionServiceImplTest { .writeValueAsString(jsonNode.get("actionCollectionWithAction")), ActionCollection.class); ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - unpublishedCollection.setDefaultToBranchedActionIdsMap( - Map.of("defaultTestActionId1", "testActionId1", "defaultTestActionId2", "testActionId2")); actionCollection.setDefaultResources(setDefaultResources(actionCollection)); unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection)); Instant deletedAt = Instant.now(); @@ -671,9 +559,15 @@ public class ActionCollectionServiceImplTest { Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.>any())) .thenReturn(Mono.just(actionCollection)); - Mockito.when(newActionService.deleteUnpublishedActionWithOptionalPermission(Mockito.any(), Mockito.any())) - .thenReturn(Mono.just( - actionCollection.getUnpublishedCollection().getActions().get(0))); + ActionDTO actionDTO = + actionCollection.getUnpublishedCollection().getActions().get(0); + NewAction newAction = new NewAction(); + newAction.setUnpublishedAction(actionDTO); + Mockito.when(newActionService.findByCollectionIdAndViewMode( + Mockito.anyString(), Mockito.anyBoolean(), Mockito.any())) + .thenReturn(Flux.just(newAction)); + + Mockito.when(newActionService.deleteGivenNewAction(Mockito.any())).thenReturn(Mono.just(actionDTO)); Mockito.when(actionCollectionRepository.save(Mockito.any())).thenAnswer(invocation -> { final ActionCollection argument = (ActionCollection) invocation.getArguments()[0]; @@ -716,6 +610,16 @@ public class ActionCollectionServiceImplTest { Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.>any())) .thenReturn(Mono.just(actionCollection)); + ActionDTO actionDTO = + actionCollection.getUnpublishedCollection().getActions().get(0); + NewAction newAction = new NewAction(); + newAction.setUnpublishedAction(actionDTO); + Mockito.when(newActionService.findByCollectionIdAndViewMode( + Mockito.anyString(), Mockito.anyBoolean(), Mockito.any())) + .thenReturn(Flux.just(newAction)); + + Mockito.when(newActionService.archiveGivenNewAction(Mockito.any())).thenReturn(Mono.just(newAction)); + Mockito.when(actionCollectionRepository.findById(Mockito.anyString())).thenReturn(Mono.just(actionCollection)); Mockito.when(actionCollectionRepository.archive(Mockito.any())).thenReturn(Mono.empty()); @@ -742,10 +646,6 @@ public class ActionCollectionServiceImplTest { .writerWithView(Views.Public.class) .writeValueAsString(jsonNode.get("actionCollectionWithAction")), ActionCollection.class); - actionCollection - .getUnpublishedCollection() - .setDefaultToBranchedActionIdsMap( - Map.of("defaultTestActionId1", "testActionId1", "defaultTestActionId2", "testActionId2")); actionCollection.setPublishedCollection(null); DefaultResources resources = new DefaultResources(); resources.setApplicationId("testApplicationId"); @@ -758,6 +658,16 @@ public class ActionCollectionServiceImplTest { Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.>any())) .thenReturn(Mono.just(actionCollection)); + ActionDTO actionDTO = + actionCollection.getUnpublishedCollection().getActions().get(0); + NewAction newAction = new NewAction(); + newAction.setUnpublishedAction(actionDTO); + Mockito.when(newActionService.findByCollectionIdAndViewMode( + Mockito.anyString(), Mockito.anyBoolean(), Mockito.any())) + .thenReturn(Flux.just(newAction)); + + Mockito.when(newActionService.archiveGivenNewAction(Mockito.any())).thenReturn(Mono.just(newAction)); + Mockito.when(actionCollectionRepository.findById(Mockito.anyString())).thenReturn(Mono.just(actionCollection)); Mockito.when(newActionService.archiveById(Mockito.any())).thenReturn(Mono.just(new NewAction())); @@ -772,90 +682,6 @@ public class ActionCollectionServiceImplTest { .verifyComplete(); } - @Test - public void testMoveCollection_toValidPage_returnsCollection() throws IOException { - final ActionCollectionMoveDTO actionCollectionMoveDTO = new ActionCollectionMoveDTO(); - actionCollectionMoveDTO.setCollectionId("testCollectionId"); - actionCollectionMoveDTO.setDestinationPageId("newPageId"); - - final ActionCollection actionCollection = new ActionCollection(); - final ActionCollectionDTO unpublishedCollection = new ActionCollectionDTO(); - unpublishedCollection.setPageId("oldPageId"); - unpublishedCollection.setName("collectionName"); - unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection)); - unpublishedCollection.setDefaultToBranchedActionIdsMap(Map.of("defaultTestActionId", "testActionId")); - actionCollection.setUnpublishedCollection(unpublishedCollection); - actionCollection.setDefaultResources(setDefaultResources(actionCollection)); - unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection)); - - ActionDTO action = new ActionDTO(); - action.setName("testAction"); - DefaultResources actionResources = new DefaultResources(); - actionResources.setActionId("testAction"); - actionResources.setPageId("newPageId"); - action.setDefaultResources(actionResources); - - Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any())) - .thenReturn(Mono.just(actionCollection)); - - Mockito.when(newActionService.findActionDTObyIdAndViewMode(Mockito.any(), Mockito.anyBoolean(), Mockito.any())) - .thenReturn(Mono.just(action)); - - Mockito.when(newActionService.updateUnpublishedAction(Mockito.any(), Mockito.any())) - .thenReturn(Mono.just(new ActionDTO())); - - Mockito.when(actionCollectionRepository.findById(Mockito.anyString())).thenReturn(Mono.just(actionCollection)); - - final QueryAllParams params = Mockito.spy(new QueryAllParams<>(null)); - doReturn(Mono.just(1)).when(params).updateFirst(Mockito.any()); - Mockito.when(actionCollectionRepository.queryBuilder()).thenReturn(params); - - PageDTO oldPageDTO = new PageDTO(); - oldPageDTO.setId("oldPageId"); - oldPageDTO.setLayouts(List.of(new Layout())); - - PageDTO newPageDTO = new PageDTO(); - newPageDTO.setId("newPageId"); - newPageDTO.setLayouts(List.of(new Layout())); - - ObjectMapper objectMapper = new ObjectMapper(); - final JsonNode jsonNode = objectMapper.readValue(mockObjects, JsonNode.class); - final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class); - DefaultResources pageDefaultResources = new DefaultResources(); - pageDefaultResources.setPageId(newPage.getId()); - newPage.setDefaultResources(pageDefaultResources); - - Mockito.when(newPageService.findPageById(Mockito.any(), Mockito.any(), Mockito.anyBoolean())) - .thenReturn(Mono.just(oldPageDTO)) - .thenReturn(Mono.just(newPageDTO)); - - Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) - .thenReturn(Mono.just(newPage)); - - LayoutDTO layout = new LayoutDTO(); - final JSONObject jsonObject = new JSONObject(); - jsonObject.put("key", "value"); - layout.setDsl(jsonObject); - - Mockito.when(updateLayoutService.unescapeMongoSpecialCharacters(Mockito.any())) - .thenReturn(jsonObject); - - Mockito.when(updateLayoutService.updateLayout(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(Mono.just(layout)); - - Mockito.when(actionCollectionRepository.setUserPermissionsInObject(Mockito.any())) - .thenReturn(Mono.just(actionCollection)); - - final Mono actionCollectionDTOMono = - layoutCollectionService.moveCollection(actionCollectionMoveDTO); - - StepVerifier.create(actionCollectionDTOMono) - .assertNext(actionCollectionDTO -> { - assertEquals("newPageId", actionCollectionDTO.getPageId()); - }) - .verifyComplete(); - } - @Test public void testGenerateActionCollectionByViewModeTestTransientFields() { ActionCollection actionCollection = new ActionCollection(); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java index 8a3d45c56a..968fda5113 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java @@ -18,6 +18,7 @@ import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.User; import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.ActionCollectionDTO; +import com.appsmith.server.dtos.ActionCollectionMoveDTO; import com.appsmith.server.dtos.ActionCollectionViewDTO; import com.appsmith.server.dtos.EntityType; import com.appsmith.server.dtos.LayoutDTO; @@ -277,6 +278,52 @@ public class ActionCollectionServiceTest { .verifyComplete(); } + @Test + @WithUserDetails(value = "api_user") + public void testMoveActionCollection_whenMovedAcrossPages_thenContainsNewPageId() { + Application application = new Application(); + application.setName(UUID.randomUUID().toString()); + + Application createdApplication = applicationPageService + .createApplication(application, workspaceId) + .block(); + + PageDTO newPageDTO = new PageDTO(); + newPageDTO.setName("newPage"); + newPageDTO.setApplicationId(createdApplication.getId()); + newPageDTO.setLayouts(List.of(new Layout())); + PageDTO newPageRes = applicationPageService.createPage(newPageDTO).block(); + + assert createdApplication != null; + final String pageId = createdApplication.getPages().get(0).getId(); + + ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO(); + actionCollectionDTO.setName("testActionCollectionSoftDeleted"); + actionCollectionDTO.setApplicationId(createdApplication.getId()); + actionCollectionDTO.setWorkspaceId(createdApplication.getWorkspaceId()); + actionCollectionDTO.setPageId(pageId); + actionCollectionDTO.setPluginId(datasource.getPluginId()); + actionCollectionDTO.setPluginType(PluginType.JS); + actionCollectionDTO.setDeletedAt(Instant.now()); + layoutCollectionService.createCollection(actionCollectionDTO, null).block(); + ActionCollection createdActionCollection = actionCollectionRepository + .findByApplicationId(createdApplication.getId(), READ_ACTIONS, null) + .blockFirst(); + + final ActionCollectionMoveDTO actionCollectionMoveDTO = new ActionCollectionMoveDTO(); + actionCollectionMoveDTO.setCollectionId(createdActionCollection.getId()); + actionCollectionMoveDTO.setDestinationPageId(newPageRes.getId()); + + final Mono actionCollectionDTOMono = + layoutCollectionService.moveCollection(actionCollectionMoveDTO); + + StepVerifier.create(actionCollectionDTOMono) + .assertNext(res -> { + assertThat(res.getPageId()).isEqualTo(newPageRes.getId()); + }) + .verifyComplete(); + } + @Test @WithUserDetails(value = "api_user") public void createValidActionCollectionAndCheckPermissions() { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java index 55581ea382..d8fbda9607 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java @@ -38,6 +38,7 @@ import com.appsmith.server.dtos.ApplicationAccessDTO; import com.appsmith.server.dtos.ApplicationJson; import com.appsmith.server.dtos.ApplicationPagesDTO; import com.appsmith.server.dtos.InviteUsersDTO; +import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.RecentlyUsedEntityDTO; import com.appsmith.server.exceptions.AppsmithError; @@ -115,7 +116,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import reactor.util.function.Tuple2; -import reactor.util.function.Tuple3; +import reactor.util.function.Tuple4; import java.time.Duration; import java.util.ArrayList; @@ -607,7 +608,7 @@ public class ApplicationServiceCETest { assertThat(page.getPolicies().stream() .map(Policy::getPermission) .collect(Collectors.toSet())) - .containsExactlyInAnyOrder( + .contains( MANAGE_PAGES.getValue(), READ_PAGES.getValue(), PAGE_CREATE_PAGE_ACTIONS.getValue(), @@ -2167,9 +2168,9 @@ public class ApplicationServiceCETest { .isEqualTo(application.getId()); newPage.getUnpublishedPage().getLayouts().forEach(layout -> { - assertThat(layout.getLayoutOnLoadActions()).hasSize(2); + assertThat(layout.getLayoutOnLoadActions()).hasSize(1); layout.getLayoutOnLoadActions().forEach(dslActionDTOS -> { - assertThat(dslActionDTOS).hasSize(1); + assertThat(dslActionDTOS).hasSize(2); dslActionDTOS.forEach(actionDTO -> { assertThat(actionDTO.getId()).isEqualTo(actionDTO.getDefaultActionId()); if (StringUtils.hasLength(actionDTO.getCollectionId())) { @@ -2193,7 +2194,7 @@ public class ApplicationServiceCETest { assertThat(action.getDefaultResources()).isNotNull(); assertThat(action.getDefaultResources().getPageId()) .isEqualTo(application.getPages().get(0).getId()); - if (!StringUtils.isEmpty(action.getDefaultResources().getCollectionId())) { + if (StringUtils.hasLength(action.getDefaultResources().getCollectionId())) { assertThat(action.getDefaultResources().getCollectionId()) .isEqualTo(action.getCollectionId()); } @@ -2209,16 +2210,6 @@ public class ApplicationServiceCETest { ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap()) - .hasSize(2); - unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .keySet() - .forEach(key -> assertThat(key) - .isEqualTo(unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .get(key))); - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); assertThat(unpublishedCollection.getDefaultResources().getPageId()) .isEqualTo(application.getPages().get(0).getId()); @@ -2325,7 +2316,7 @@ public class ApplicationServiceCETest { .collectList(); Map> originalResourceIds = new HashMap<>(); - Mono resultMono = originalApplicationMono + Tuple4 tuple4 = originalApplicationMono .zipWhen(application -> newPageService.findPageById( application.getPages().get(0).getId(), READ_PAGES, false)) .flatMap(tuple -> { @@ -2429,53 +2420,51 @@ public class ApplicationServiceCETest { testPage.getId(), testPage.getApplicationId(), layout.getId(), layout), Mono.just(tuple.getT3())); }) - .flatMap(tuple -> { - List pageIds = new ArrayList<>(), collectionIds = new ArrayList<>(); - ActionCollectionDTO collectionDTO = tuple.getT1(); - collectionIds.add(collectionDTO.getId()); - tuple.getT4().getPages().forEach(page -> pageIds.add(page.getId())); + .block(); - originalResourceIds.put("pageIds", pageIds); - originalResourceIds.put("collectionIds", collectionIds); + List pageIds = new ArrayList<>(), collectionIds = new ArrayList<>(); + ActionCollectionDTO collectionDTO = tuple4.getT1(); + collectionIds.add(collectionDTO.getId()); + tuple4.getT4().getPages().forEach(page -> pageIds.add(page.getId())); - String deletedActionIdWithinActionCollection = - String.valueOf(collectionDTO.getDefaultToBranchedActionIdsMap().values().stream() - .findAny() - .orElse(null)); + originalResourceIds.put("pageIds", pageIds); + originalResourceIds.put("collectionIds", collectionIds); - return newActionService - .deleteUnpublishedAction(deletedActionIdWithinActionCollection) - .thenMany(newActionService.findAllByApplicationIdAndViewMode( - tuple.getT4().getId(), false, READ_ACTIONS, null)) - .collectList() - .flatMap(actionList -> { - List actionIds = actionList.stream() - .map(BaseDomain::getId) - .collect(Collectors.toList()); - originalResourceIds.put("actionIds", actionIds); - return applicationPageService.cloneApplication( - tuple.getT4().getId(), null); - }); + String deletedActionIdWithinActionCollection = newActionService + .findByCollectionIdAndViewMode(collectionDTO.getId(), false, null) + .blockFirst() + .getId(); + + Application application1 = newActionService + .deleteUnpublishedAction(deletedActionIdWithinActionCollection) + .thenMany(newActionService.findAllByApplicationIdAndViewMode( + tuple4.getT4().getId(), false, READ_ACTIONS, null)) + .collectList() + .flatMap(actionList -> { + List actionIds = + actionList.stream().map(BaseDomain::getId).collect(Collectors.toList()); + originalResourceIds.put("actionIds", actionIds); + return applicationPageService.cloneApplication( + tuple4.getT4().getId(), null); }) - .cache(); + .block(); - StepVerifier.create(resultMono.zipWhen(application -> Mono.zip( + StepVerifier.create(Mono.zip( newActionService - .findAllByApplicationIdAndViewMode(application.getId(), false, READ_ACTIONS, null) + .findAllByApplicationIdAndViewMode(application1.getId(), false, READ_ACTIONS, null) .collectList(), actionCollectionService - .findAllByApplicationIdAndViewMode(application.getId(), false, READ_ACTIONS, null) + .findAllByApplicationIdAndViewMode(application1.getId(), false, READ_ACTIONS, null) .collectList(), newPageService - .findNewPagesByApplicationId(application.getId(), READ_PAGES) + .findNewPagesByApplicationId(application1.getId(), READ_PAGES) .collectList(), - defaultPermissionGroupsMono))) + defaultPermissionGroupsMono)) .assertNext(tuple -> { - Application application = tuple.getT1(); // cloned application - List actionList = tuple.getT2().getT1(); - List actionCollectionList = tuple.getT2().getT2(); - List pageList = tuple.getT2().getT3(); - List permissionGroups = tuple.getT2().getT4(); + List actionList = tuple.getT1(); + List actionCollectionList = tuple.getT2(); + List pageList = tuple.getT3(); + List permissionGroups = tuple.getT4(); PermissionGroup adminPermissionGroup = permissionGroups.stream() .filter(permissionGroup -> permissionGroup.getName().startsWith(ADMINISTRATOR)) @@ -2517,17 +2506,17 @@ public class ApplicationServiceCETest { viewerPermissionGroup.getId())) .build(); - assertThat(application).isNotNull(); - assertThat(application.isAppIsExample()).isFalse(); - assertThat(application.getId()).isNotNull(); - assertThat(application.getName()) + assertThat(application1).isNotNull(); + assertThat(application1.isAppIsExample()).isFalse(); + assertThat(application1.getId()).isNotNull(); + assertThat(application1.getName()) .isEqualTo( "ApplicationServiceTest-clone-application-deleted-action-within-collection Copy"); - assertThat(application.getPolicies()).containsAll(Set.of(manageAppPolicy, readAppPolicy)); - assertThat(application.getWorkspaceId()).isEqualTo(workspaceId); - assertThat(application.getModifiedBy()).isEqualTo("api_user"); - assertThat(application.getUpdatedAt()).isNotNull(); - List pages = application.getPages(); + assertThat(application1.getPolicies()).containsAll(Set.of(manageAppPolicy, readAppPolicy)); + assertThat(application1.getWorkspaceId()).isEqualTo(workspaceId); + assertThat(application1.getModifiedBy()).isEqualTo("api_user"); + assertThat(application1.getUpdatedAt()).isNotNull(); + List pages = application1.getPages(); Set pageIdsFromApplication = pages.stream().map(ApplicationPage::getId).collect(Collectors.toSet()); Set pageIdsFromDb = @@ -2538,7 +2527,7 @@ public class ApplicationServiceCETest { assertThat(pageList).isNotEmpty(); for (NewPage page : pageList) { assertThat(page.getPolicies()).containsAll(Set.of(managePagePolicy, readPagePolicy)); - assertThat(page.getApplicationId()).isEqualTo(application.getId()); + assertThat(page.getApplicationId()).isEqualTo(application1.getId()); } assertThat(pageList).isNotEmpty(); @@ -2546,12 +2535,12 @@ public class ApplicationServiceCETest { assertThat(newPage.getDefaultResources()).isNotNull(); assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId()); assertThat(newPage.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); + .isEqualTo(application1.getId()); newPage.getUnpublishedPage().getLayouts().forEach(layout -> { - assertThat(layout.getLayoutOnLoadActions()).hasSize(2); + assertThat(layout.getLayoutOnLoadActions()).hasSize(1); layout.getLayoutOnLoadActions().forEach(dslActionDTOS -> { - assertThat(dslActionDTOS).hasSize(1); + assertThat(dslActionDTOS).hasSize(2); dslActionDTOS.forEach(actionDTO -> { assertThat(actionDTO.getId()).isEqualTo(actionDTO.getDefaultActionId()); if (StringUtils.hasLength(actionDTO.getCollectionId())) { @@ -2569,13 +2558,13 @@ public class ApplicationServiceCETest { assertThat(newAction.getDefaultResources().getActionId()) .isEqualTo(newAction.getId()); assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); + .isEqualTo(application1.getId()); ActionDTO action = newAction.getUnpublishedAction(); assertThat(action.getDefaultResources()).isNotNull(); assertThat(action.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); - if (!StringUtils.isEmpty(action.getDefaultResources().getCollectionId())) { + .isEqualTo(application1.getPages().get(0).getId()); + if (StringUtils.hasLength(action.getDefaultResources().getCollectionId())) { assertThat(action.getDefaultResources().getCollectionId()) .isEqualTo(action.getCollectionId()); } @@ -2587,24 +2576,13 @@ public class ApplicationServiceCETest { assertThat(actionCollection.getDefaultResources().getCollectionId()) .isEqualTo(actionCollection.getId()); assertThat(actionCollection.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); + .isEqualTo(application1.getId()); ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - // We should have single entry as other action is deleted from the parent application - assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap()) - .hasSize(1); - unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .keySet() - .forEach(key -> assertThat(key) - .isEqualTo(unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .get(key))); - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); assertThat(unpublishedCollection.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); + .isEqualTo(application1.getPages().get(0).getId()); }); }) .verifyComplete(); @@ -2775,7 +2753,7 @@ public class ApplicationServiceCETest { Application.NavigationSetting appNavigationSetting = new Application.NavigationSetting(); appNavigationSetting.setOrientation("top"); testApplication.getUnpublishedApplicationDetail().setNavigationSetting(appNavigationSetting); - Mono> resultMono = applicationPageService + Mono> resultMono = applicationPageService .createApplication(testApplication, workspaceId) .flatMap(application -> { PageDTO page = new PageDTO(); @@ -2827,6 +2805,10 @@ public class ApplicationServiceCETest { .flatMap(tuple1 -> { ActionDTO savedAction = tuple1.getT1(); ActionCollectionDTO savedActionCollection = tuple1.getT2(); + String actionId = savedActionCollection + .getActions() + .get(0) + .getId(); return applicationPageService .publish(testApplication.getId(), true) .then(applicationPageService.deleteUnpublishedPage(page.getId())) @@ -2836,24 +2818,18 @@ public class ApplicationServiceCETest { this.getArchivedResource(savedAction.getId(), NewAction.class), (Mono) this.getArchivedResource( savedActionCollection.getId(), ActionCollection.class), - (Mono) this.getArchivedResource(page.getId(), NewPage.class))); + (Mono) this.getArchivedResource(page.getId(), NewPage.class), + (Mono) this.getArchivedResource(actionId, NewAction.class))); }); }) .cache(); - Mono archivedActionFromActionCollectionMono = resultMono.flatMap(tuple -> { - final Optional actionId = - tuple.getT2().getUnpublishedCollection().getDefaultToBranchedActionIdsMap().values().stream() - .findFirst(); - return (Mono) this.getArchivedResource(actionId.get(), NewAction.class); - }); - - StepVerifier.create(resultMono.zipWith(archivedActionFromActionCollectionMono)) + StepVerifier.create(resultMono) .assertNext(tuple -> { - NewAction archivedAction = tuple.getT1().getT1(); - ActionCollection archivedActionCollection = tuple.getT1().getT2(); - NewPage archivedPage = tuple.getT1().getT3(); - NewAction archivedActionFromActionCollection = tuple.getT2(); + NewAction archivedAction = tuple.getT1(); + ActionCollection archivedActionCollection = tuple.getT2(); + NewPage archivedPage = tuple.getT3(); + NewAction archivedActionFromActionCollection = tuple.getT4(); assertThat(archivedAction.getDeletedAt()).isNotNull(); @@ -3747,7 +3723,7 @@ public class ApplicationServiceCETest { String appName = "deleteApplicationWithPagesAndActions"; testApplication.setName(appName); - Mono> resultMono = applicationPageService + Mono> resultMono = applicationPageService .createApplication(testApplication, workspaceId) .flatMap(application -> { PageDTO page = new PageDTO(); @@ -3804,29 +3780,31 @@ public class ApplicationServiceCETest { .findById(page.getApplicationId(), MANAGE_APPLICATIONS) .flatMap(application -> applicationPageService.deleteApplication(application.getId())) - .flatMap(ignored -> Mono.zip( - (Mono) - this.getArchivedResource(savedAction.getId(), NewAction.class), - (Mono) this.getArchivedResource( - savedActionCollection.getId(), ActionCollection.class), - (Mono) this.getArchivedResource(page.getId(), NewPage.class))); + .flatMap(ignored -> { + final String actionId = savedActionCollection + .getActions() + .get(0) + .getId(); + return Mono.zip( + (Mono) this.getArchivedResource( + savedAction.getId(), NewAction.class), + (Mono) this.getArchivedResource( + savedActionCollection.getId(), ActionCollection.class), + (Mono) + this.getArchivedResource(page.getId(), NewPage.class), + (Mono) + this.getArchivedResource(actionId, NewAction.class)); + }); }); }) .cache(); - Mono archivedActionFromActionCollectionMono = resultMono.flatMap(tuple -> { - final Optional actionId = - tuple.getT2().getUnpublishedCollection().getDefaultToBranchedActionIdsMap().values().stream() - .findFirst(); - return (Mono) this.getArchivedResource(actionId.get(), NewAction.class); - }); - - StepVerifier.create(resultMono.zipWith(archivedActionFromActionCollectionMono)) + StepVerifier.create(resultMono) .assertNext(tuple -> { - NewAction archivedAction = tuple.getT1().getT1(); - ActionCollection archivedActionCollection = tuple.getT1().getT2(); - NewPage archivedPage = tuple.getT1().getT3(); - NewAction archivedActionFromActionCollection = tuple.getT2(); + NewAction archivedAction = tuple.getT1(); + ActionCollection archivedActionCollection = tuple.getT2(); + NewPage archivedPage = tuple.getT3(); + NewAction archivedActionFromActionCollection = tuple.getT4(); assertThat(archivedAction.getDeletedAt()).isNotNull(); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ApplicationForkingServiceTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ApplicationForkingServiceTests.java index cea77630c5..8643b8b883 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ApplicationForkingServiceTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ApplicationForkingServiceTests.java @@ -441,16 +441,6 @@ public class ApplicationForkingServiceTests { ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap()) - .hasSize(1); - unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .keySet() - .forEach(key -> assertThat(key) - .isEqualTo(unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .get(key))); - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); assertThat(unpublishedCollection.getDefaultResources().getPageId()) .isEqualTo(application.getPages().get(0).getId()); @@ -623,16 +613,6 @@ public class ApplicationForkingServiceTests { ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap()) - .hasSize(1); - unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .keySet() - .forEach(key -> assertThat(key) - .isEqualTo(unpublishedCollection - .getDefaultToBranchedActionIdsMap() - .get(key))); - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); assertThat(unpublishedCollection.getDefaultResources().getPageId()) .isEqualTo(application.getPages().get(0).getId()); diff --git a/app/server/appsmith-server/src/test/resources/test_assets/ActionCollectionServiceTest/mockObjects.json b/app/server/appsmith-server/src/test/resources/test_assets/ActionCollectionServiceTest/mockObjects.json index e290ff1362..4ebfccf806 100644 --- a/app/server/appsmith-server/src/test/resources/test_assets/ActionCollectionServiceTest/mockObjects.json +++ b/app/server/appsmith-server/src/test/resources/test_assets/ActionCollectionServiceTest/mockObjects.json @@ -51,14 +51,6 @@ "name": "testCollection", "pageId": "testPageId", "pluginId": "testPluginId", - "defaultToBranchedActionIdsMap": [ - { - "defaultTestActionId1": "testActionId1" - }, - { - "defaultTestActionId2": "testActionId2" - } - ], "actions": [ { "id": "testActionId1" @@ -71,12 +63,7 @@ "publishedCollection": { "name": "testCollection", "pageId": "testPageId", - "pluginId": "testPluginId", - "defaultToBranchedActionIdsMap": [ - { - "defaultTestActionId1": "testActionId1" - } - ] + "pluginId": "testPluginId" } }, "actionCollectionDTOWithModifiedActions": { @@ -86,19 +73,6 @@ "name": "testCollection", "pageId": "testPageId", "pluginId": "testPluginId", - "defaultToBranchedActionIdsMap": [ - { - "defaultTestActionId1": "testActionId1" - }, - { - "defaultTestActionId3": "testActionId3" - } - ], - "defaultToBranchedArchivedActionIdsMap": [ - { - "defaultTestActionId2": "testActionId2" - } - ], "actions": [ { "id": "testActionId1" @@ -106,11 +80,6 @@ { "id": "testActionId3" } - ], - "archivedActions": [ - { - "id": "testActionId2" - } ] }, "actionCollectionAfterModifiedActions": { @@ -123,19 +92,6 @@ "name": "testCollection", "pageId": "testPageId", "pluginId": "testPluginId", - "defaultToBranchedActionIdsMap": [ - { - "defaultTestActionId1": "testActionId1" - }, - { - "defaultTestActionId3": "testActionId3" - } - ], - "defaultToBranchedArchivedActionIdsMap": [ - { - "defaultTestActionId2": "testActionId2" - } - ], "actions": [ { "id": "testActionId1" @@ -143,22 +99,12 @@ { "id": "testActionId3" } - ], - "archivedActions": [ - { - "id": "testActionId2" - } ] }, "publishedCollection": { "name": "testCollection", "pageId": "testPageId", - "pluginId": "testPluginId", - "defaultToBranchedActionIdsMap": [ - { - "defaultTestActionId1": "testActionId1" - } - ] + "pluginId": "testPluginId" } } }