fix: Forking with JS collections (#8799)
This commit is contained in:
parent
7016d9f6d0
commit
295f8b9631
|
|
@ -16,4 +16,6 @@ public interface CustomActionCollectionRepository extends AppsmithRepository<Act
|
||||||
Flux<ActionCollection> findAllActionCollectionsByNameAndPageIdsAndViewMode(String name, List<String> pageIds, boolean viewMode, AclPermission aclPermission, Sort sort);
|
Flux<ActionCollection> findAllActionCollectionsByNameAndPageIdsAndViewMode(String name, List<String> pageIds, boolean viewMode, AclPermission aclPermission, Sort sort);
|
||||||
|
|
||||||
Flux<ActionCollection> findByPageId(String pageId, AclPermission permission);
|
Flux<ActionCollection> findByPageId(String pageId, AclPermission permission);
|
||||||
|
|
||||||
|
Flux<ActionCollection> findByPageId(String pageId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,4 +122,9 @@ public class CustomActionCollectionRepositoryImpl extends BaseAppsmithRepository
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Flux<ActionCollection> findByPageId(String pageId) {
|
||||||
|
return this.findByPageId(pageId, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public interface ActionCollectionService extends CrudService<ActionCollection, S
|
||||||
|
|
||||||
Mono<ActionCollectionDTO> findActionCollectionDTObyIdAndViewMode(String id, Boolean viewMode, AclPermission permission);
|
Mono<ActionCollectionDTO> findActionCollectionDTObyIdAndViewMode(String id, Boolean viewMode, AclPermission permission);
|
||||||
|
|
||||||
Flux<ActionCollection> findByPageId(String pageId, AclPermission permission);
|
|
||||||
|
|
||||||
Flux<ActionCollectionViewDTO> getActionCollectionsForViewMode(String applicationId);
|
Flux<ActionCollectionViewDTO> getActionCollectionsForViewMode(String applicationId);
|
||||||
|
|
||||||
|
Flux<ActionCollection> findByPageId(String pageId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -303,8 +303,8 @@ public class ActionCollectionServiceImpl extends BaseService<ActionCollectionRep
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Flux<ActionCollection> findByPageId(String pageId, AclPermission permission) {
|
public Flux<ActionCollection> findByPageId(String pageId) {
|
||||||
return repository.findByPageId(pageId, permission);
|
return repository.findByPageId(pageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -593,7 +593,7 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
|
||||||
/**
|
/**
|
||||||
* Only delete unpublished action collection and not the entire action collection.
|
* Only delete unpublished action collection and not the entire action collection.
|
||||||
*/
|
*/
|
||||||
Mono<List<ActionCollectionDTO>> archivedActionCollectionsMono = actionCollectionService.findByPageId(page.getId(), MANAGE_ACTIONS)
|
Mono<List<ActionCollectionDTO>> archivedActionCollectionsMono = actionCollectionService.findByPageId(page.getId())
|
||||||
.flatMap(actionCollection -> {
|
.flatMap(actionCollection -> {
|
||||||
log.debug("Going to archive actionCollectionId: {} for applicationId: {}", actionCollection.getId(), id);
|
log.debug("Going to archive actionCollectionId: {} for applicationId: {}", actionCollection.getId(), id);
|
||||||
return actionCollectionService.deleteUnpublishedActionCollection(actionCollection.getId());
|
return actionCollectionService.deleteUnpublishedActionCollection(actionCollection.getId());
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,15 @@ import com.appsmith.external.helpers.AppsmithEventContext;
|
||||||
import com.appsmith.external.helpers.AppsmithEventContextType;
|
import com.appsmith.external.helpers.AppsmithEventContextType;
|
||||||
import com.appsmith.external.models.AuthenticationDTO;
|
import com.appsmith.external.models.AuthenticationDTO;
|
||||||
import com.appsmith.external.models.BaseDomain;
|
import com.appsmith.external.models.BaseDomain;
|
||||||
|
import com.appsmith.external.models.Datasource;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Application;
|
import com.appsmith.server.domains.Application;
|
||||||
import com.appsmith.server.domains.ApplicationPage;
|
import com.appsmith.server.domains.ApplicationPage;
|
||||||
import com.appsmith.external.models.Datasource;
|
|
||||||
import com.appsmith.server.domains.Layout;
|
import com.appsmith.server.domains.Layout;
|
||||||
import com.appsmith.server.domains.NewPage;
|
import com.appsmith.server.domains.NewPage;
|
||||||
import com.appsmith.server.domains.Organization;
|
import com.appsmith.server.domains.Organization;
|
||||||
import com.appsmith.server.domains.User;
|
import com.appsmith.server.domains.User;
|
||||||
|
import com.appsmith.server.dtos.ActionCollectionDTO;
|
||||||
import com.appsmith.server.dtos.ActionDTO;
|
import com.appsmith.server.dtos.ActionDTO;
|
||||||
import com.appsmith.server.dtos.DslActionDTO;
|
import com.appsmith.server.dtos.DslActionDTO;
|
||||||
import com.appsmith.server.dtos.PageDTO;
|
import com.appsmith.server.dtos.PageDTO;
|
||||||
|
|
@ -20,11 +21,13 @@ import com.appsmith.server.exceptions.AppsmithException;
|
||||||
import com.appsmith.server.repositories.DatasourceRepository;
|
import com.appsmith.server.repositories.DatasourceRepository;
|
||||||
import com.appsmith.server.repositories.NewPageRepository;
|
import com.appsmith.server.repositories.NewPageRepository;
|
||||||
import com.appsmith.server.repositories.OrganizationRepository;
|
import com.appsmith.server.repositories.OrganizationRepository;
|
||||||
|
import com.appsmith.server.services.ActionCollectionService;
|
||||||
import com.appsmith.server.services.ApplicationPageService;
|
import com.appsmith.server.services.ApplicationPageService;
|
||||||
import com.appsmith.server.services.ApplicationService;
|
import com.appsmith.server.services.ApplicationService;
|
||||||
import com.appsmith.server.services.ConfigService;
|
import com.appsmith.server.services.ConfigService;
|
||||||
import com.appsmith.server.services.DatasourceService;
|
import com.appsmith.server.services.DatasourceService;
|
||||||
import com.appsmith.server.services.LayoutActionService;
|
import com.appsmith.server.services.LayoutActionService;
|
||||||
|
import com.appsmith.server.services.LayoutCollectionService;
|
||||||
import com.appsmith.server.services.NewActionService;
|
import com.appsmith.server.services.NewActionService;
|
||||||
import com.appsmith.server.services.OrganizationService;
|
import com.appsmith.server.services.OrganizationService;
|
||||||
import com.appsmith.server.services.SessionUserService;
|
import com.appsmith.server.services.SessionUserService;
|
||||||
|
|
@ -38,7 +41,6 @@ import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.util.function.Tuple2;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -64,6 +66,8 @@ public class ExamplesOrganizationCloner {
|
||||||
private final NewPageRepository newPageRepository;
|
private final NewPageRepository newPageRepository;
|
||||||
private final NewActionService newActionService;
|
private final NewActionService newActionService;
|
||||||
private final LayoutActionService layoutActionService;
|
private final LayoutActionService layoutActionService;
|
||||||
|
private final ActionCollectionService actionCollectionService;
|
||||||
|
private final LayoutCollectionService layoutCollectionService;
|
||||||
|
|
||||||
public Mono<Organization> cloneExamplesOrganization() {
|
public Mono<Organization> cloneExamplesOrganization() {
|
||||||
return sessionUserService
|
return sessionUserService
|
||||||
|
|
@ -223,7 +227,7 @@ public class ExamplesOrganizationCloner {
|
||||||
? applicationPageService.makePageDefault(savedPage).thenReturn(savedPage)
|
? applicationPageService.makePageDefault(savedPage).thenReturn(savedPage)
|
||||||
: Mono.just(savedPage))
|
: Mono.just(savedPage))
|
||||||
.flatMap(savedPage -> newPageRepository.findById(savedPage.getId()))
|
.flatMap(savedPage -> newPageRepository.findById(savedPage.getId()))
|
||||||
.flatMapMany(savedPage -> {
|
.flatMap(savedPage -> {
|
||||||
clonedPages.add(savedPage);
|
clonedPages.add(savedPage);
|
||||||
return newActionService
|
return newActionService
|
||||||
.findByPageId(templatePageId)
|
.findByPageId(templatePageId)
|
||||||
|
|
@ -232,45 +236,83 @@ public class ExamplesOrganizationCloner {
|
||||||
log.info("Preparing action for cloning {} {}.", action.getName(), newAction.getId());
|
log.info("Preparing action for cloning {} {}.", action.getName(), newAction.getId());
|
||||||
action.setPageId(savedPage.getId());
|
action.setPageId(savedPage.getId());
|
||||||
return newAction;
|
return newAction;
|
||||||
|
})
|
||||||
|
.flatMap(newAction -> {
|
||||||
|
final String originalActionId = newAction.getId();
|
||||||
|
log.info("Creating clone of action {}", originalActionId);
|
||||||
|
makePristine(newAction);
|
||||||
|
newAction.setOrganizationId(toOrganizationId);
|
||||||
|
ActionDTO action = newAction.getUnpublishedAction();
|
||||||
|
final String originalCollectionId = action.getCollectionId();
|
||||||
|
action.setCollectionId(null);
|
||||||
|
|
||||||
|
Mono<ActionDTO> actionMono = Mono.just(action);
|
||||||
|
final Datasource datasourceInsideAction = action.getDatasource();
|
||||||
|
if (datasourceInsideAction != null) {
|
||||||
|
if (datasourceInsideAction.getId() != null) {
|
||||||
|
final String datasourceId = datasourceInsideAction.getId();
|
||||||
|
if (!cloneDatasourceMonos.containsKey(datasourceId)) {
|
||||||
|
cloneDatasourceMonos.put(datasourceId, cloneDatasource(datasourceId, toOrganizationId).cache());
|
||||||
|
}
|
||||||
|
actionMono = cloneDatasourceMonos.get(datasourceId)
|
||||||
|
.map(newDatasource -> {
|
||||||
|
action.setDatasource(newDatasource);
|
||||||
|
return action;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
datasourceInsideAction.setOrganizationId(toOrganizationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Mono.zip(actionMono
|
||||||
|
.flatMap(actionDTO -> layoutActionService.createAction(
|
||||||
|
actionDTO, new AppsmithEventContext(AppsmithEventContextType.CLONE_PAGE))
|
||||||
|
)
|
||||||
|
.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<String, String>::new, (map, tuple3) -> map.put(tuple3.getT2(), tuple3.getT1()))
|
||||||
|
.flatMap(actionIdsMap -> {
|
||||||
|
// 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
|
||||||
|
makePristine(actionCollection);
|
||||||
|
final ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection();
|
||||||
|
unpublishedCollection.setPageId(savedPage.getId());
|
||||||
|
actionCollection.setOrganizationId(toOrganizationId);
|
||||||
|
actionCollection.setApplicationId(savedPage.getApplicationId());
|
||||||
|
actionCollectionService.generateAndSetPolicies(savedPage, actionCollection);
|
||||||
|
|
||||||
|
// Replace all action Ids from map
|
||||||
|
final HashSet<String> newActionIds = new HashSet<>();
|
||||||
|
unpublishedCollection
|
||||||
|
.getActionIds()
|
||||||
|
.stream()
|
||||||
|
.forEach(oldActionId -> newActionIds.add(actionIdsMap.get(oldActionId)));
|
||||||
|
unpublishedCollection.setActionIds(newActionIds);
|
||||||
|
return actionCollectionService.create(actionCollection)
|
||||||
|
.flatMap(newlyCreatedActionCollection -> {
|
||||||
|
return Flux.fromIterable(newActionIds)
|
||||||
|
.flatMap(newActionService::findById)
|
||||||
|
.flatMap(newlyCreatedAction -> {
|
||||||
|
newlyCreatedAction.getUnpublishedAction().setCollectionId(newlyCreatedAction.getId());
|
||||||
|
return newActionService.update(newlyCreatedAction.getId(), newlyCreatedAction);
|
||||||
|
})
|
||||||
|
.collectList();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.collectList()
|
||||||
|
.thenReturn(actionIdsMap);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.flatMap(newAction -> {
|
.flatMap(actionIdsMap -> updateActionIdsInClonedPages(clonedPages, actionIdsMap))
|
||||||
final String originalActionId = newAction.getId();
|
|
||||||
log.info("Creating clone of action {}", originalActionId);
|
|
||||||
makePristine(newAction);
|
|
||||||
newAction.setOrganizationId(toOrganizationId);
|
|
||||||
ActionDTO action = newAction.getUnpublishedAction();
|
|
||||||
action.setCollectionId(null);
|
|
||||||
|
|
||||||
Mono<ActionDTO> actionMono = Mono.just(action);
|
|
||||||
final Datasource datasourceInsideAction = action.getDatasource();
|
|
||||||
if (datasourceInsideAction != null) {
|
|
||||||
if (datasourceInsideAction.getId() != null) {
|
|
||||||
final String datasourceId = datasourceInsideAction.getId();
|
|
||||||
if (!cloneDatasourceMonos.containsKey(datasourceId)) {
|
|
||||||
cloneDatasourceMonos.put(datasourceId, cloneDatasource(datasourceId, toOrganizationId).cache());
|
|
||||||
}
|
|
||||||
actionMono = cloneDatasourceMonos.get(datasourceId)
|
|
||||||
.map(newDatasource -> {
|
|
||||||
action.setDatasource(newDatasource);
|
|
||||||
return action;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
datasourceInsideAction.setOrganizationId(toOrganizationId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return actionMono
|
|
||||||
.flatMap(actionDTO -> layoutActionService.createAction(
|
|
||||||
actionDTO, new AppsmithEventContext(AppsmithEventContextType.CLONE_PAGE))
|
|
||||||
)
|
|
||||||
.map(ActionDTO::getId)
|
|
||||||
.zipWith(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.
|
|
||||||
.collectMap(Tuple2::getT2, Tuple2::getT1)
|
|
||||||
.flatMapMany(actionIdsMap -> updateActionIdsInClonedPages(clonedPages, actionIdsMap))
|
|
||||||
// Now publish all the example applications which have been cloned to ensure that there is a
|
// Now publish all the example applications which have been cloned to ensure that there is a
|
||||||
// view mode for the newly created user.
|
// view mode for the newly created user.
|
||||||
.then(Mono.just(newApplicationIds))
|
.then(Mono.just(newApplicationIds))
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import com.appsmith.external.models.ActionConfiguration;
|
||||||
import com.appsmith.external.models.AuthenticationResponse;
|
import com.appsmith.external.models.AuthenticationResponse;
|
||||||
import com.appsmith.external.models.Connection;
|
import com.appsmith.external.models.Connection;
|
||||||
import com.appsmith.external.models.DBAuth;
|
import com.appsmith.external.models.DBAuth;
|
||||||
|
import com.appsmith.external.models.Datasource;
|
||||||
import com.appsmith.external.models.DatasourceConfiguration;
|
import com.appsmith.external.models.DatasourceConfiguration;
|
||||||
import com.appsmith.external.models.Endpoint;
|
import com.appsmith.external.models.Endpoint;
|
||||||
import com.appsmith.external.models.OAuth2;
|
import com.appsmith.external.models.OAuth2;
|
||||||
|
|
@ -11,15 +12,18 @@ import com.appsmith.external.models.PEMCertificate;
|
||||||
import com.appsmith.external.models.Property;
|
import com.appsmith.external.models.Property;
|
||||||
import com.appsmith.external.models.SSLDetails;
|
import com.appsmith.external.models.SSLDetails;
|
||||||
import com.appsmith.external.models.UploadedFile;
|
import com.appsmith.external.models.UploadedFile;
|
||||||
|
import com.appsmith.external.plugins.PluginExecutor;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Application;
|
import com.appsmith.server.domains.Application;
|
||||||
import com.appsmith.server.domains.ApplicationPage;
|
import com.appsmith.server.domains.ApplicationPage;
|
||||||
import com.appsmith.external.models.Datasource;
|
|
||||||
import com.appsmith.server.domains.Layout;
|
import com.appsmith.server.domains.Layout;
|
||||||
import com.appsmith.server.domains.NewAction;
|
import com.appsmith.server.domains.NewAction;
|
||||||
import com.appsmith.server.domains.NewPage;
|
import com.appsmith.server.domains.NewPage;
|
||||||
import com.appsmith.server.domains.Organization;
|
import com.appsmith.server.domains.Organization;
|
||||||
import com.appsmith.server.domains.Plugin;
|
import com.appsmith.server.domains.Plugin;
|
||||||
|
import com.appsmith.server.domains.PluginType;
|
||||||
|
import com.appsmith.server.domains.User;
|
||||||
|
import com.appsmith.server.dtos.ActionCollectionDTO;
|
||||||
import com.appsmith.server.dtos.ActionDTO;
|
import com.appsmith.server.dtos.ActionDTO;
|
||||||
import com.appsmith.server.dtos.DslActionDTO;
|
import com.appsmith.server.dtos.DslActionDTO;
|
||||||
import com.appsmith.server.dtos.PageDTO;
|
import com.appsmith.server.dtos.PageDTO;
|
||||||
|
|
@ -33,6 +37,7 @@ import com.appsmith.server.services.ApplicationPageService;
|
||||||
import com.appsmith.server.services.ApplicationService;
|
import com.appsmith.server.services.ApplicationService;
|
||||||
import com.appsmith.server.services.DatasourceService;
|
import com.appsmith.server.services.DatasourceService;
|
||||||
import com.appsmith.server.services.LayoutActionService;
|
import com.appsmith.server.services.LayoutActionService;
|
||||||
|
import com.appsmith.server.services.LayoutCollectionService;
|
||||||
import com.appsmith.server.services.NewActionService;
|
import com.appsmith.server.services.NewActionService;
|
||||||
import com.appsmith.server.services.NewPageService;
|
import com.appsmith.server.services.NewPageService;
|
||||||
import com.appsmith.server.services.OrganizationService;
|
import com.appsmith.server.services.OrganizationService;
|
||||||
|
|
@ -111,6 +116,9 @@ public class ExamplesOrganizationClonerTests {
|
||||||
@MockBean
|
@MockBean
|
||||||
private PluginExecutorHelper pluginExecutorHelper;
|
private PluginExecutorHelper pluginExecutorHelper;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
PluginExecutor pluginExecutor;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private LayoutActionService layoutActionService;
|
private LayoutActionService layoutActionService;
|
||||||
|
|
||||||
|
|
@ -128,11 +136,15 @@ public class ExamplesOrganizationClonerTests {
|
||||||
|
|
||||||
private Plugin installedPlugin;
|
private Plugin installedPlugin;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LayoutCollectionService layoutCollectionService;
|
||||||
|
|
||||||
private static class OrganizationData {
|
private static class OrganizationData {
|
||||||
Organization organization;
|
Organization organization;
|
||||||
List<Application> applications = new ArrayList<>();
|
List<Application> applications = new ArrayList<>();
|
||||||
List<Datasource> datasources = new ArrayList<>();
|
List<Datasource> datasources = new ArrayList<>();
|
||||||
List<ActionDTO> actions = new ArrayList<>();
|
List<ActionDTO> actions = new ArrayList<>();
|
||||||
|
List<ActionCollectionDTO> actionCollections = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mono<OrganizationData> loadOrganizationData(Organization organization) {
|
public Mono<OrganizationData> loadOrganizationData(Organization organization) {
|
||||||
|
|
@ -148,7 +160,9 @@ public class ExamplesOrganizationClonerTests {
|
||||||
.findAllByOrganizationId(organization.getId(), READ_DATASOURCES)
|
.findAllByOrganizationId(organization.getId(), READ_DATASOURCES)
|
||||||
.map(data.datasources::add),
|
.map(data.datasources::add),
|
||||||
getActionsInOrganization(organization)
|
getActionsInOrganization(organization)
|
||||||
.map(data.actions::add)
|
.map(data.actions::add),
|
||||||
|
getActionCollectionsInOrganization(organization)
|
||||||
|
.map(data.actionCollections::add)
|
||||||
)
|
)
|
||||||
.thenReturn(data);
|
.thenReturn(data);
|
||||||
}
|
}
|
||||||
|
|
@ -180,6 +194,7 @@ public class ExamplesOrganizationClonerTests {
|
||||||
assertThat(data.applications).isEmpty();
|
assertThat(data.applications).isEmpty();
|
||||||
assertThat(data.datasources).isEmpty();
|
assertThat(data.datasources).isEmpty();
|
||||||
assertThat(data.actions).isEmpty();
|
assertThat(data.actions).isEmpty();
|
||||||
|
assertThat(data.actionCollections).isEmpty();
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
@ -233,6 +248,7 @@ public class ExamplesOrganizationClonerTests {
|
||||||
|
|
||||||
assertThat(data.datasources).isEmpty();
|
assertThat(data.datasources).isEmpty();
|
||||||
assertThat(data.actions).isEmpty();
|
assertThat(data.actions).isEmpty();
|
||||||
|
assertThat(data.actionCollections).isEmpty();
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
@ -303,6 +319,7 @@ public class ExamplesOrganizationClonerTests {
|
||||||
|
|
||||||
assertThat(data.datasources).isEmpty();
|
assertThat(data.datasources).isEmpty();
|
||||||
assertThat(data.actions).isEmpty();
|
assertThat(data.actions).isEmpty();
|
||||||
|
assertThat(data.actionCollections).isEmpty();
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
@ -345,6 +362,7 @@ public class ExamplesOrganizationClonerTests {
|
||||||
assertThat(data.applications).isEmpty();
|
assertThat(data.applications).isEmpty();
|
||||||
assertThat(data.datasources).isEmpty();
|
assertThat(data.datasources).isEmpty();
|
||||||
assertThat(data.actions).isEmpty();
|
assertThat(data.actions).isEmpty();
|
||||||
|
assertThat(data.actionCollections).isEmpty();
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
@ -453,6 +471,7 @@ public class ExamplesOrganizationClonerTests {
|
||||||
assertThat(data.datasources).isEmpty();
|
assertThat(data.datasources).isEmpty();
|
||||||
assertThat(data.applications).isEmpty();
|
assertThat(data.applications).isEmpty();
|
||||||
assertThat(data.actions).isEmpty();
|
assertThat(data.actions).isEmpty();
|
||||||
|
assertThat(data.actionCollections).isEmpty();
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
@ -514,6 +533,7 @@ public class ExamplesOrganizationClonerTests {
|
||||||
|
|
||||||
assertThat(data.applications).isEmpty();
|
assertThat(data.applications).isEmpty();
|
||||||
assertThat(data.actions).isEmpty();
|
assertThat(data.actions).isEmpty();
|
||||||
|
assertThat(data.actionCollections).isEmpty();
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
@ -582,144 +602,136 @@ public class ExamplesOrganizationClonerTests {
|
||||||
|
|
||||||
assertThat(data.datasources).isEmpty();
|
assertThat(data.datasources).isEmpty();
|
||||||
assertThat(data.actions).isEmpty();
|
assertThat(data.actions).isEmpty();
|
||||||
|
assertThat(data.actionCollections).isEmpty();
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithUserDetails(value = "api_user")
|
@WithUserDetails(value = "api_user")
|
||||||
public void cloneOrganizationWithDatasourcesAndApplicationsAndActions() {
|
public void cloneOrganizationWithDatasourcesAndApplicationsAndActionsAndCollections() {
|
||||||
Organization newOrganization = new Organization();
|
Organization newOrganization = new Organization();
|
||||||
newOrganization.setName("Template Organization 2");
|
newOrganization.setName("Template Organization 2");
|
||||||
final Mono<OrganizationData> resultMono = Mono
|
final Organization organization = organizationService.create(newOrganization).block();
|
||||||
.zip(
|
final User user = sessionUserService.getCurrentUser().block();
|
||||||
organizationService.create(newOrganization),
|
|
||||||
sessionUserService.getCurrentUser()
|
|
||||||
)
|
|
||||||
.flatMap(tuple -> {
|
|
||||||
final Organization organization = tuple.getT1();
|
|
||||||
|
|
||||||
final Application app1 = new Application();
|
final Application app1 = new Application();
|
||||||
app1.setName("first application");
|
app1.setName("first application");
|
||||||
app1.setOrganizationId(organization.getId());
|
app1.setOrganizationId(organization.getId());
|
||||||
app1.setIsPublic(true);
|
app1.setIsPublic(true);
|
||||||
|
|
||||||
final Application app2 = new Application();
|
final Application app2 = new Application();
|
||||||
app2.setName("second application");
|
app2.setName("second application");
|
||||||
app2.setOrganizationId(organization.getId());
|
app2.setOrganizationId(organization.getId());
|
||||||
app2.setIsPublic(true);
|
app2.setIsPublic(true);
|
||||||
|
|
||||||
final Datasource ds1 = new Datasource();
|
final Datasource ds1 = new Datasource();
|
||||||
ds1.setName("datasource 1");
|
ds1.setName("datasource 1");
|
||||||
ds1.setOrganizationId(organization.getId());
|
ds1.setOrganizationId(organization.getId());
|
||||||
ds1.setPluginId(installedPlugin.getId());
|
ds1.setPluginId(installedPlugin.getId());
|
||||||
|
|
||||||
final Datasource ds2 = new Datasource();
|
final Datasource ds2 = new Datasource();
|
||||||
ds2.setName("datasource 2");
|
ds2.setName("datasource 2");
|
||||||
ds2.setOrganizationId(organization.getId());
|
ds2.setOrganizationId(organization.getId());
|
||||||
ds2.setPluginId(installedPlugin.getId());
|
ds2.setPluginId(installedPlugin.getId());
|
||||||
|
|
||||||
return Mono
|
final Application app = applicationPageService.createApplication(app1).block();
|
||||||
.zip(
|
final Application app2Again = applicationPageService.createApplication(app2).block();
|
||||||
applicationPageService.createApplication(app1),
|
final Datasource ds1WithId = datasourceService.create(ds1).block();
|
||||||
applicationPageService.createApplication(app2),
|
final Datasource ds2WithId = datasourceService.create(ds2).block();
|
||||||
datasourceService.create(ds1),
|
|
||||||
datasourceService.create(ds2)
|
|
||||||
)
|
|
||||||
.flatMap(tuple1 -> {
|
|
||||||
final Application app = tuple1.getT1();
|
|
||||||
final String pageId1 = app.getPages().get(0).getId();
|
|
||||||
final Datasource ds1WithId = tuple1.getT3();
|
|
||||||
|
|
||||||
final PageDTO newPage = new PageDTO();
|
final String pageId1 = app.getPages().get(0).getId();
|
||||||
newPage.setName("A New Page");
|
|
||||||
newPage.setApplicationId(app.getId());
|
|
||||||
newPage.setLayouts(new ArrayList<>());
|
|
||||||
final Layout layout = new Layout();
|
|
||||||
layout.setId(new ObjectId().toString());
|
|
||||||
JSONObject dsl = new JSONObject();
|
|
||||||
dsl.put("widgetName", "testWidget");
|
|
||||||
JSONArray temp = new JSONArray();
|
|
||||||
temp.addAll(List.of(new JSONObject(Map.of("key", "testField"))));
|
|
||||||
dsl.put("dynamicBindingPathList", temp);
|
|
||||||
dsl.put("testField", "draft {{ newPageAction.data }}");
|
|
||||||
layout.setDsl(dsl);
|
|
||||||
JSONObject publishedDsl = new JSONObject(dsl);
|
|
||||||
publishedDsl.put("testField", "published {{ newPageAction.data }}");
|
|
||||||
layout.setPublishedDsl(publishedDsl);
|
|
||||||
final DslActionDTO actionDTO = new DslActionDTO();
|
|
||||||
final HashSet<DslActionDTO> dslActionDTOS = new HashSet<>(List.of(actionDTO));
|
|
||||||
layout.setLayoutOnLoadActions(List.of(dslActionDTOS));
|
|
||||||
newPage.getLayouts().add(layout);
|
|
||||||
|
|
||||||
final ActionDTO newPageAction = new ActionDTO();
|
final PageDTO newPage = new PageDTO();
|
||||||
newPageAction.setName("newPageAction");
|
newPage.setName("A New Page");
|
||||||
newPageAction.setOrganizationId(organization.getId());
|
newPage.setApplicationId(app.getId());
|
||||||
newPageAction.setDatasource(ds1WithId);
|
newPage.setLayouts(new ArrayList<>());
|
||||||
newPageAction.setPluginId(installedPlugin.getId());
|
final Layout layout = new Layout();
|
||||||
newPageAction.setActionConfiguration(new ActionConfiguration());
|
layout.setId(new ObjectId().toString());
|
||||||
newPageAction.getActionConfiguration().setHttpMethod(HttpMethod.GET);
|
JSONObject dsl = new JSONObject();
|
||||||
|
dsl.put("widgetName", "testWidget");
|
||||||
|
JSONArray temp = new JSONArray();
|
||||||
|
temp.addAll(List.of(new JSONObject(Map.of("key", "testField"))));
|
||||||
|
dsl.put("dynamicBindingPathList", temp);
|
||||||
|
dsl.put("testField", "draft {{ newPageAction.data }}");
|
||||||
|
layout.setDsl(dsl);
|
||||||
|
JSONObject publishedDsl = new JSONObject(dsl);
|
||||||
|
publishedDsl.put("testField", "published {{ newPageAction.data }}");
|
||||||
|
layout.setPublishedDsl(publishedDsl);
|
||||||
|
final DslActionDTO actionDTO = new DslActionDTO();
|
||||||
|
final HashSet<DslActionDTO> dslActionDTOS = new HashSet<>(List.of(actionDTO));
|
||||||
|
layout.setLayoutOnLoadActions(List.of(dslActionDTOS));
|
||||||
|
newPage.getLayouts().add(layout);
|
||||||
|
|
||||||
final ActionDTO action1 = new ActionDTO();
|
final ActionDTO newPageAction = new ActionDTO();
|
||||||
action1.setName("action1");
|
newPageAction.setName("newPageAction");
|
||||||
action1.setPageId(pageId1);
|
newPageAction.setOrganizationId(organization.getId());
|
||||||
action1.setOrganizationId(organization.getId());
|
newPageAction.setDatasource(ds1WithId);
|
||||||
action1.setDatasource(ds1WithId);
|
newPageAction.setPluginId(installedPlugin.getId());
|
||||||
action1.setPluginId(installedPlugin.getId());
|
newPageAction.setActionConfiguration(new ActionConfiguration());
|
||||||
|
newPageAction.getActionConfiguration().setHttpMethod(HttpMethod.GET);
|
||||||
|
|
||||||
final ActionDTO action2 = new ActionDTO();
|
final ActionDTO action1 = new ActionDTO();
|
||||||
action2.setPageId(pageId1);
|
action1.setName("action1");
|
||||||
action2.setName("action2");
|
action1.setPageId(pageId1);
|
||||||
action2.setOrganizationId(organization.getId());
|
action1.setOrganizationId(organization.getId());
|
||||||
action2.setDatasource(ds1WithId);
|
action1.setDatasource(ds1WithId);
|
||||||
action2.setPluginId(installedPlugin.getId());
|
action1.setPluginId(installedPlugin.getId());
|
||||||
|
|
||||||
final Application app2Again = tuple1.getT2();
|
final String pageId2 = app2Again.getPages().get(0).getId();
|
||||||
final String pageId2 = app2Again.getPages().get(0).getId();
|
|
||||||
final Datasource ds2WithId = tuple1.getT4();
|
|
||||||
|
|
||||||
final ActionDTO action3 = new ActionDTO();
|
final ActionDTO action3 = new ActionDTO();
|
||||||
action3.setName("action3");
|
action3.setName("action3");
|
||||||
action3.setPageId(pageId2);
|
action3.setPageId(pageId2);
|
||||||
action3.setOrganizationId(organization.getId());
|
action3.setOrganizationId(organization.getId());
|
||||||
action3.setDatasource(ds2WithId);
|
action3.setDatasource(ds2WithId);
|
||||||
action3.setPluginId(installedPlugin.getId());
|
action3.setPluginId(installedPlugin.getId());
|
||||||
|
|
||||||
final ActionDTO action4 = new ActionDTO();
|
Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())).thenReturn(Mono.just(pluginExecutor));
|
||||||
action4.setPageId(pageId2);
|
Mockito.when(pluginExecutor.getHintMessages(Mockito.any(), Mockito.any()))
|
||||||
action4.setName("action4");
|
.thenReturn(Mono.zip(Mono.just(new HashSet<>()), Mono.just(new HashSet<>())));
|
||||||
action4.setOrganizationId(organization.getId());
|
|
||||||
action4.setDatasource(ds2WithId);
|
|
||||||
action4.setPluginId(installedPlugin.getId());
|
|
||||||
|
|
||||||
return Mono.when(
|
Datasource jsDatasource = new Datasource();
|
||||||
applicationPageService.createPage(newPage)
|
jsDatasource.setName("Default Database");
|
||||||
.flatMap(page -> {
|
jsDatasource.setOrganizationId(organization.getId());
|
||||||
newPageAction.setPageId(page.getId());
|
Plugin installedJsPlugin = pluginRepository.findByPackageName("installed-js-plugin").block();
|
||||||
return applicationPageService.addPageToApplication(app, page, false)
|
assert installedJsPlugin != null;
|
||||||
.then(layoutActionService.createSingleAction(newPageAction))
|
jsDatasource.setPluginId(installedJsPlugin.getId());
|
||||||
.flatMap(savedAction -> layoutActionService.updateSingleAction(savedAction.getId(), savedAction))
|
|
||||||
.then(newPageService.findPageById(page.getId(), READ_PAGES, false));
|
ActionCollectionDTO actionCollectionDTO1 = new ActionCollectionDTO();
|
||||||
})
|
actionCollectionDTO1.setName("testCollection1");
|
||||||
.map(tuple2 -> {
|
actionCollectionDTO1.setPageId(app.getPages().get(0).getId());
|
||||||
log.info("Created action and added page to app {}", tuple2);
|
actionCollectionDTO1.setApplicationId(app.getId());
|
||||||
return tuple2;
|
actionCollectionDTO1.setOrganizationId(organization.getId());
|
||||||
}),
|
actionCollectionDTO1.setPluginId(jsDatasource.getPluginId());
|
||||||
layoutActionService.createSingleAction(action1),
|
ActionDTO action5 = new ActionDTO();
|
||||||
layoutActionService.createSingleAction(action2),
|
action5.setName("run");
|
||||||
layoutActionService.createSingleAction(action3),
|
action5.setActionConfiguration(new ActionConfiguration());
|
||||||
layoutActionService.createSingleAction(action4)
|
action5.getActionConfiguration().setBody("mockBody");
|
||||||
).thenReturn(List.of(tuple1.getT1(), tuple1.getT2()));
|
actionCollectionDTO1.setActions(List.of(action5));
|
||||||
})
|
actionCollectionDTO1.setPluginType(PluginType.JS);
|
||||||
.flatMap(applications ->
|
|
||||||
examplesOrganizationCloner.cloneOrganizationForUser(
|
applicationPageService.createPage(newPage)
|
||||||
organization.getId(),
|
.flatMap(page -> {
|
||||||
tuple.getT2(),
|
newPageAction.setPageId(page.getId());
|
||||||
Flux.fromIterable(applications),
|
return applicationPageService.addPageToApplication(app, page, false)
|
||||||
Flux.empty()
|
.then(layoutActionService.createSingleAction(newPageAction))
|
||||||
)
|
.flatMap(savedAction -> layoutActionService.updateSingleAction(savedAction.getId(), savedAction))
|
||||||
);
|
.then(newPageService.findPageById(page.getId(), READ_PAGES, false));
|
||||||
})
|
})
|
||||||
|
.map(tuple2 -> {
|
||||||
|
log.info("Created action and added page to app {}", tuple2);
|
||||||
|
return tuple2;
|
||||||
|
}).block();
|
||||||
|
layoutActionService.createSingleAction(action1).block();
|
||||||
|
layoutActionService.createSingleAction(action3).block();
|
||||||
|
layoutCollectionService.createCollection(actionCollectionDTO1).block();
|
||||||
|
|
||||||
|
final Mono<OrganizationData> resultMono = examplesOrganizationCloner.cloneOrganizationForUser(
|
||||||
|
organization.getId(),
|
||||||
|
user,
|
||||||
|
Flux.fromIterable(List.of(app, app2Again)),
|
||||||
|
Flux.empty())
|
||||||
.doOnError(error -> log.error("Error preparing data for test", error))
|
.doOnError(error -> log.error("Error preparing data for test", error))
|
||||||
.flatMap(this::loadOrganizationData);
|
.flatMap(this::loadOrganizationData);
|
||||||
|
|
||||||
|
|
@ -736,16 +748,15 @@ public class ExamplesOrganizationClonerTests {
|
||||||
"second application"
|
"second application"
|
||||||
);
|
);
|
||||||
|
|
||||||
final Application firstApplication = data.applications.stream().filter(app -> app.getName().equals("first application")).findFirst().orElse(null);
|
final Application firstApplication = data.applications.stream().filter(appFirst -> appFirst.getName().equals("first application")).findFirst().orElse(null);
|
||||||
assert firstApplication != null;
|
assert firstApplication != null;
|
||||||
assertThat(firstApplication.getPages().stream().filter(ApplicationPage::isDefault).count()).isEqualTo(1);
|
assertThat(firstApplication.getPages().stream().filter(ApplicationPage::isDefault).count()).isEqualTo(1);
|
||||||
final NewPage newPage = mongoTemplate.findOne(Query.query(Criteria.where("applicationId").is(firstApplication.getId()).and("unpublishedPage.name").is("A New Page")), NewPage.class);
|
final NewPage newPage1 = mongoTemplate.findOne(Query.query(Criteria.where("applicationId").is(firstApplication.getId()).and("unpublishedPage.name").is("A New Page")), NewPage.class);
|
||||||
assert newPage != null;
|
assert newPage1 != null;
|
||||||
log.debug("new page is : {}", newPage.toString());
|
final String actionId = newPage1.getUnpublishedPage().getLayouts().get(0).getLayoutOnLoadActions().get(0).iterator().next().getId();
|
||||||
final String actionId = newPage.getUnpublishedPage().getLayouts().get(0).getLayoutOnLoadActions().get(0).iterator().next().getId();
|
final NewAction newPageAction1 = mongoTemplate.findOne(Query.query(Criteria.where("id").is(actionId)), NewAction.class);
|
||||||
final NewAction newPageAction = mongoTemplate.findOne(Query.query(Criteria.where("id").is(actionId)), NewAction.class);
|
assert newPageAction1 != null;
|
||||||
assert newPageAction != null;
|
assertThat(newPageAction1.getOrganizationId()).isEqualTo(data.organization.getId());
|
||||||
assertThat(newPageAction.getOrganizationId()).isEqualTo(data.organization.getId());
|
|
||||||
|
|
||||||
assertThat(data.datasources).hasSize(2);
|
assertThat(data.datasources).hasSize(2);
|
||||||
assertThat(map(data.datasources, Datasource::getName)).containsExactlyInAnyOrder(
|
assertThat(map(data.datasources, Datasource::getName)).containsExactlyInAnyOrder(
|
||||||
|
|
@ -753,16 +764,18 @@ public class ExamplesOrganizationClonerTests {
|
||||||
"datasource 2"
|
"datasource 2"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertThat(data.actions).hasSize(5);
|
assertThat(data.actions).hasSize(4);
|
||||||
assertThat(getUnpublishedActionName(data.actions)).containsExactlyInAnyOrder(
|
assertThat(getUnpublishedActionName(data.actions)).containsExactlyInAnyOrder(
|
||||||
"newPageAction",
|
"newPageAction",
|
||||||
"action1",
|
"action1",
|
||||||
"action2",
|
|
||||||
"action3",
|
"action3",
|
||||||
"action4"
|
"run"
|
||||||
);
|
);
|
||||||
|
assertThat(data.actionCollections).hasSize(1);
|
||||||
|
assertThat(data.actionCollections.get(0).getActionIds()).hasSize(1);
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -1014,4 +1027,13 @@ public class ExamplesOrganizationClonerTests {
|
||||||
.flatMap(page -> newActionService.getUnpublishedActions(new LinkedMultiValueMap<>(
|
.flatMap(page -> newActionService.getUnpublishedActions(new LinkedMultiValueMap<>(
|
||||||
Map.of(FieldName.PAGE_ID, Collections.singletonList(page.getId())))));
|
Map.of(FieldName.PAGE_ID, Collections.singletonList(page.getId())))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Flux<ActionCollectionDTO> getActionCollectionsInOrganization(Organization organization) {
|
||||||
|
return applicationService
|
||||||
|
.findByOrganizationId(organization.getId(), READ_APPLICATIONS)
|
||||||
|
// fetch the unpublished pages
|
||||||
|
.flatMap(application -> newPageService.findByApplicationId(application.getId(), READ_PAGES, false))
|
||||||
|
.flatMap(page -> actionCollectionService.getActionCollectionsByViewMode(new LinkedMultiValueMap<>(
|
||||||
|
Map.of(FieldName.PAGE_ID, Collections.singletonList(page.getId()))), false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user