chore: First page load time optimization: Introduce server side changes for consolidated API (#29875)
This commit is contained in:
parent
fdc3502e58
commit
c214222cee
|
|
@ -11,7 +11,7 @@ public interface PluginConstants {
|
|||
String AMAZON_S3_PLUGIN = "amazons3-plugin";
|
||||
String GOOGLE_SHEETS_PLUGIN = "google-sheets-plugin";
|
||||
String REST_API_PLUGIN = "restapi-plugin";
|
||||
String GRAPH_QL_PLUGIN = "graphql-plugin";
|
||||
String GRAPHQL_PLUGIN = "graphql-plugin";
|
||||
String OPEN_AI_PLUGIN = "openai-plugin";
|
||||
String ANTHROPIC_PLUGIN = "anthropic-plugin";
|
||||
String GOOGLE_AI_PLUGIN = "googleai-plugin";
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ import static com.appsmith.server.constants.Url.TENANT_URL;
|
|||
import static com.appsmith.server.constants.Url.THEME_URL;
|
||||
import static com.appsmith.server.constants.Url.USAGE_PULSE_URL;
|
||||
import static com.appsmith.server.constants.Url.USER_URL;
|
||||
import static com.appsmith.server.constants.ce.UrlCE.CONSOLIDATED_API_URL;
|
||||
import static java.time.temporal.ChronoUnit.DAYS;
|
||||
|
||||
@EnableWebFluxSecurity
|
||||
|
|
@ -211,7 +212,8 @@ public class SecurityConfig {
|
|||
ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, USER_URL + "/resendEmailVerification"),
|
||||
ServerWebExchangeMatchers.pathMatchers(
|
||||
HttpMethod.POST, USER_URL + "/verifyEmailVerificationToken"),
|
||||
ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, PRODUCT_ALERT + "/alert"))
|
||||
ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, PRODUCT_ALERT + "/alert"),
|
||||
ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, CONSOLIDATED_API_URL))
|
||||
.permitAll()
|
||||
.pathMatchers("/public/**", "/oauth2/**")
|
||||
.permitAll()
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public class UrlCE {
|
|||
public static final String CUSTOM_JS_LIB_URL = BASE_URL + VERSION + "/libraries";
|
||||
public static final String PRODUCT_ALERT = BASE_URL + VERSION + "/product-alert";
|
||||
public static final String SEARCH_ENTITY_URL = BASE_URL + VERSION + "/search-entities";
|
||||
public static final String CONSOLIDATED_API_URL = BASE_URL + VERSION + "/consolidated-api";
|
||||
|
||||
// Sub-paths
|
||||
public static final String MOCKS = "/mocks";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package com.appsmith.server.controllers;
|
||||
|
||||
import com.appsmith.external.views.Views;
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.constants.Url;
|
||||
import com.appsmith.server.domains.ApplicationMode;
|
||||
import com.appsmith.server.dtos.ConsolidatedAPIResponseDTO;
|
||||
import com.appsmith.server.dtos.ResponseDTO;
|
||||
import com.appsmith.server.services.ConsolidatedAPIService;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping(Url.CONSOLIDATED_API_URL)
|
||||
public class ConsolidatedAPIController {
|
||||
private final ConsolidatedAPIService consolidatedAPIService;
|
||||
|
||||
public ConsolidatedAPIController(ConsolidatedAPIService consolidatedAPIService) {
|
||||
this.consolidatedAPIService = consolidatedAPIService;
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is meant to be used by the client application at the time of 1st page load. Client currently makes
|
||||
* several API calls to fetch all the required data. This endpoint consolidates all that data and returns them as
|
||||
* response hence enabling the client to fetch the required data via a single API call only.
|
||||
*/
|
||||
@JsonView(Views.Public.class)
|
||||
@GetMapping
|
||||
public Mono<ResponseDTO<ConsolidatedAPIResponseDTO>> getAllDataForFirstPageLoad(
|
||||
@RequestParam(required = false) String applicationId,
|
||||
@RequestParam(required = false) String defaultPageId,
|
||||
@RequestParam(required = false) ApplicationMode mode,
|
||||
@RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) {
|
||||
log.debug(
|
||||
"Going to fetch consolidatedAPI response for applicationId: {}, defaultPageId: {}, branchName: {}, "
|
||||
+ "mode: {}",
|
||||
applicationId,
|
||||
defaultPageId,
|
||||
branchName,
|
||||
mode);
|
||||
return consolidatedAPIService
|
||||
.getConsolidatedInfoForPageLoad(defaultPageId, applicationId, branchName, mode)
|
||||
.map(consolidatedAPIResponseDTO ->
|
||||
new ResponseDTO<>(HttpStatus.OK.value(), consolidatedAPIResponseDTO, null));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.appsmith.server.dtos;
|
||||
|
||||
import com.appsmith.external.models.ActionDTO;
|
||||
import com.appsmith.external.models.Datasource;
|
||||
import com.appsmith.server.domains.CustomJSLib;
|
||||
import com.appsmith.server.domains.Plugin;
|
||||
import com.appsmith.server.domains.Tenant;
|
||||
import com.appsmith.server.domains.Theme;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class serves as a DTO for the response data returned via the consolidated API endpoint call
|
||||
* (v1/consolidated-api) . Each identifier in the class represents the data returned from a unique endpoint. The
|
||||
* endpoint info is mentioned on top of each identifier.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ConsolidatedAPIResponseDTO {
|
||||
/* v1/users/me */
|
||||
ResponseDTO<UserProfileDTO> v1UsersMeResp;
|
||||
|
||||
/* v1/users/features */
|
||||
ResponseDTO<Map<String, Boolean>> v1UsersFeaturesResp;
|
||||
|
||||
/* v1/tenants/current */
|
||||
ResponseDTO<Tenant> v1TenantsCurrentResp;
|
||||
|
||||
/* v1/product-alert/alert */
|
||||
ResponseDTO<ProductAlertResponseDTO> v1ProductAlertResp;
|
||||
|
||||
/* v1/pages */
|
||||
ResponseDTO<ApplicationPagesDTO> v1PagesResp;
|
||||
|
||||
/* v1/actions/view */
|
||||
ResponseDTO<List<ActionViewDTO>> v1ActionsViewResp;
|
||||
|
||||
/* v1/actions */
|
||||
ResponseDTO<List<ActionDTO>> v1ActionsResp;
|
||||
|
||||
/* v1/collections/actions/view */
|
||||
ResponseDTO<List<ActionCollectionViewDTO>> v1CollectionsActionsViewResp;
|
||||
|
||||
/* v1/collections/actions */
|
||||
ResponseDTO<List<ActionCollectionDTO>> v1CollectionsActionsResp;
|
||||
|
||||
/* v1/themes/applications/{applicationId}/current */
|
||||
ResponseDTO<Theme> v1ThemesApplicationCurrentModeResp;
|
||||
|
||||
/* v1/themes/applications/{applicationId} */
|
||||
ResponseDTO<List<Theme>> v1ThemesResp;
|
||||
|
||||
/* v1/pages/{pageId}/view */
|
||||
ResponseDTO<PageDTO> v1PublishedPageResp;
|
||||
|
||||
/* v1/pages/{pageId} */
|
||||
ResponseDTO<PageDTO> v1PageResp;
|
||||
|
||||
/* v1/pages/{pageId} - for all pages */
|
||||
ResponseDTO<List<PageDTO>> v1PageDSLs;
|
||||
|
||||
/* v1/libraries/{applicationId}/view */
|
||||
ResponseDTO<List<CustomJSLib>> v1LibrariesApplicationResp;
|
||||
|
||||
/* v1/plugins */
|
||||
ResponseDTO<List<Plugin>> v1PluginsResp;
|
||||
|
||||
/* v1/datasources */
|
||||
ResponseDTO<List<Datasource>> v1DatasourcesResp;
|
||||
|
||||
/* v1/plugins/{pluginId}/form - for all plugins used in app */
|
||||
ResponseDTO<Map<String, Map>> v1PluginFormConfigsResp;
|
||||
|
||||
/* v1/datasources/mock */
|
||||
ResponseDTO<List<MockDataSet>> v1DatasourcesMockResp;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import com.appsmith.server.domains.ApplicationMode;
|
||||
import com.appsmith.server.dtos.ConsolidatedAPIResponseDTO;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface ConsolidatedAPIService {
|
||||
Mono<ConsolidatedAPIResponseDTO> getConsolidatedInfoForPageLoad(
|
||||
String defaultPageId, String applicationId, String branchName, ApplicationMode mode);
|
||||
}
|
||||
|
|
@ -0,0 +1,501 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import com.appsmith.external.exceptions.ErrorDTO;
|
||||
import com.appsmith.external.models.ActionDTO;
|
||||
import com.appsmith.external.models.CreatorContextType;
|
||||
import com.appsmith.external.models.Datasource;
|
||||
import com.appsmith.server.actioncollections.base.ActionCollectionService;
|
||||
import com.appsmith.server.applications.base.ApplicationService;
|
||||
import com.appsmith.server.datasources.base.DatasourceService;
|
||||
import com.appsmith.server.domains.ApplicationMode;
|
||||
import com.appsmith.server.domains.CustomJSLib;
|
||||
import com.appsmith.server.domains.Plugin;
|
||||
import com.appsmith.server.domains.Tenant;
|
||||
import com.appsmith.server.domains.Theme;
|
||||
import com.appsmith.server.dtos.ActionCollectionDTO;
|
||||
import com.appsmith.server.dtos.ActionCollectionViewDTO;
|
||||
import com.appsmith.server.dtos.ActionViewDTO;
|
||||
import com.appsmith.server.dtos.ApplicationPagesDTO;
|
||||
import com.appsmith.server.dtos.ConsolidatedAPIResponseDTO;
|
||||
import com.appsmith.server.dtos.MockDataDTO;
|
||||
import com.appsmith.server.dtos.MockDataSet;
|
||||
import com.appsmith.server.dtos.PageDTO;
|
||||
import com.appsmith.server.dtos.ProductAlertResponseDTO;
|
||||
import com.appsmith.server.dtos.ResponseDTO;
|
||||
import com.appsmith.server.dtos.UserProfileDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.jslibs.base.CustomJSLibService;
|
||||
import com.appsmith.server.newactions.base.NewActionService;
|
||||
import com.appsmith.server.newpages.base.NewPageService;
|
||||
import com.appsmith.server.plugins.base.PluginService;
|
||||
import com.appsmith.server.themes.base.ThemeService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.appsmith.external.constants.PluginConstants.PackageName.GRAPHQL_PLUGIN;
|
||||
import static com.appsmith.external.constants.PluginConstants.PackageName.REST_API_PLUGIN;
|
||||
import static com.appsmith.server.constants.ce.FieldNameCE.APPLICATION_ID;
|
||||
import static com.appsmith.server.constants.ce.FieldNameCE.APP_MODE;
|
||||
import static com.appsmith.server.constants.ce.FieldNameCE.WORKSPACE_ID;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
|
||||
private static final String FEATURE_FLAG_RELEASE_SERVER_DSL_MIGRATIONS_ENABLED =
|
||||
"release_server_dsl_migrations_enabled";
|
||||
public static final int INTERNAL_SERVER_ERROR_STATUS = AppsmithError.INTERNAL_SERVER_ERROR.getHttpErrorCode();
|
||||
public static final String INTERNAL_SERVER_ERROR_CODE = AppsmithError.INTERNAL_SERVER_ERROR.getAppErrorCode();
|
||||
|
||||
private final SessionUserService sessionUserService;
|
||||
private final UserService userService;
|
||||
private final UserDataService userDataService;
|
||||
private final TenantService tenantService;
|
||||
private final ProductAlertService productAlertService;
|
||||
private final NewPageService newPageService;
|
||||
private final NewActionService newActionService;
|
||||
private final ActionCollectionService actionCollectionService;
|
||||
private final ThemeService themeService;
|
||||
private final ApplicationPageService applicationPageService;
|
||||
private final CustomJSLibService customJSLibService;
|
||||
private final PluginService pluginService;
|
||||
private final ApplicationService applicationService;
|
||||
private final DatasourceService datasourceService;
|
||||
private final MockDataService mockDataService;
|
||||
|
||||
public ConsolidatedAPIServiceImpl(
|
||||
SessionUserService sessionUserService,
|
||||
UserService userService,
|
||||
UserDataService userDataService,
|
||||
TenantService tenantService,
|
||||
ProductAlertService productAlertService,
|
||||
NewPageService newPageService,
|
||||
NewActionService newActionService,
|
||||
ActionCollectionService actionCollectionService,
|
||||
ThemeService themeService,
|
||||
ApplicationPageService applicationPageService,
|
||||
CustomJSLibService customJSLibService,
|
||||
PluginService pluginService,
|
||||
ApplicationService applicationService,
|
||||
DatasourceService datasourceService,
|
||||
MockDataService mockDataService) {
|
||||
this.sessionUserService = sessionUserService;
|
||||
this.userService = userService;
|
||||
this.userDataService = userDataService;
|
||||
this.tenantService = tenantService;
|
||||
this.productAlertService = productAlertService;
|
||||
this.newPageService = newPageService;
|
||||
this.newActionService = newActionService;
|
||||
this.actionCollectionService = actionCollectionService;
|
||||
this.themeService = themeService;
|
||||
this.applicationPageService = applicationPageService;
|
||||
this.customJSLibService = customJSLibService;
|
||||
this.pluginService = pluginService;
|
||||
this.applicationService = applicationService;
|
||||
this.datasourceService = datasourceService;
|
||||
this.mockDataService = mockDataService;
|
||||
}
|
||||
|
||||
<T> ResponseDTO<T> getSuccessResponse(T data) {
|
||||
return new ResponseDTO<>(HttpStatus.OK.value(), data, null);
|
||||
}
|
||||
|
||||
<T> Mono<ResponseDTO<T>> getErrorResponseMono(Throwable error, Class<T> type) {
|
||||
if (error instanceof AppsmithException appsmithException) {
|
||||
return Mono.just(new ResponseDTO<T>(
|
||||
appsmithException.getHttpStatus(),
|
||||
new ErrorDTO(
|
||||
appsmithException.getAppErrorCode(),
|
||||
appsmithException.getErrorType(),
|
||||
appsmithException.getMessage(),
|
||||
appsmithException.getTitle())));
|
||||
}
|
||||
|
||||
return Mono.just(new ResponseDTO<T>(
|
||||
INTERNAL_SERVER_ERROR_STATUS, new ErrorDTO(INTERNAL_SERVER_ERROR_CODE, error.getMessage())));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is meant to be used by the client application at the time of 1st page load. Client currently makes
|
||||
* several API calls to fetch all the required data. This method consolidates all that data and returns them as
|
||||
* response hence enabling the client to fetch the required data via a single API call only.
|
||||
*
|
||||
* PLEASE TAKE CARE TO USE .cache() FOR Mono THAT GETS REUSED SO THAT FIRST PAGE LOAD PERFORMANCE DOES NOT DEGRADE.
|
||||
*/
|
||||
@Override
|
||||
public Mono<ConsolidatedAPIResponseDTO> getConsolidatedInfoForPageLoad(
|
||||
String defaultPageId, String applicationId, String branchName, ApplicationMode mode) {
|
||||
|
||||
/* if either of pageId or applicationId are provided then application mode must also be provided */
|
||||
if (mode == null && (!isBlank(defaultPageId) || !isBlank(applicationId))) {
|
||||
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, APP_MODE));
|
||||
}
|
||||
|
||||
/* This object will serve as a container to hold the response of this method*/
|
||||
ConsolidatedAPIResponseDTO consolidatedAPIResponseDTO = new ConsolidatedAPIResponseDTO();
|
||||
|
||||
/* Get user profile data */
|
||||
Mono<ResponseDTO<UserProfileDTO>> userProfileDTOResponseDTOMono = sessionUserService
|
||||
.getCurrentUser()
|
||||
.flatMap(userService::buildUserProfileDTO)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, UserProfileDTO.class));
|
||||
|
||||
/* Get all feature flags data */
|
||||
Mono<ResponseDTO<Map>> featureFlagsForCurrentUserResponseDTOMonoCache = userDataService
|
||||
.getFeatureFlagsForCurrentUser()
|
||||
.map(res -> (Map) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, Map.class))
|
||||
.cache();
|
||||
|
||||
/* Get tenant config data */
|
||||
Mono<ResponseDTO<Tenant>> tenantResponseDTOMono = tenantService
|
||||
.getTenantConfiguration()
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, Tenant.class));
|
||||
|
||||
/* Get any product alert info */
|
||||
Mono<ResponseDTO<ProductAlertResponseDTO>> productAlertResponseDTOMono = productAlertService
|
||||
.getSingleApplicableMessage()
|
||||
.map(messages -> {
|
||||
if (!messages.isEmpty()) {
|
||||
return messages.get(0);
|
||||
}
|
||||
|
||||
return new ProductAlertResponseDTO();
|
||||
})
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, ProductAlertResponseDTO.class));
|
||||
|
||||
if (isBlank(defaultPageId) && isBlank(applicationId)) {
|
||||
|
||||
List<Mono<?>> listOfCommonResponseMono = List.of(
|
||||
userProfileDTOResponseDTOMono,
|
||||
featureFlagsForCurrentUserResponseDTOMonoCache,
|
||||
tenantResponseDTOMono,
|
||||
productAlertResponseDTOMono);
|
||||
|
||||
return Mono.zip(listOfCommonResponseMono, responseArray -> {
|
||||
consolidatedAPIResponseDTO.setV1UsersMeResp((ResponseDTO<UserProfileDTO>) responseArray[0]);
|
||||
consolidatedAPIResponseDTO.setV1UsersFeaturesResp((ResponseDTO<Map<String, Boolean>>) responseArray[1]);
|
||||
consolidatedAPIResponseDTO.setV1TenantsCurrentResp((ResponseDTO<Tenant>) responseArray[2]);
|
||||
consolidatedAPIResponseDTO.setV1ProductAlertResp(
|
||||
(ResponseDTO<ProductAlertResponseDTO>) responseArray[3]);
|
||||
|
||||
return consolidatedAPIResponseDTO;
|
||||
});
|
||||
}
|
||||
|
||||
/* Get view mode - EDIT or PUBLISHED */
|
||||
boolean isViewMode = ApplicationMode.PUBLISHED.equals(mode);
|
||||
|
||||
/* Fetch application id if not provided */
|
||||
Mono<String> applicationIdMonoCache;
|
||||
if (isBlank(applicationId)) {
|
||||
applicationIdMonoCache = applicationPageService
|
||||
.getPage(defaultPageId, isViewMode)
|
||||
.map(PageDTO::getApplicationId)
|
||||
.cache();
|
||||
} else {
|
||||
applicationIdMonoCache = Mono.just(applicationId).cache();
|
||||
}
|
||||
|
||||
/* Get all pages in application */
|
||||
Mono<ResponseDTO<ApplicationPagesDTO>> applicationPagesDTOResponseDTOMonoCache = applicationIdMonoCache
|
||||
.flatMap(appId -> newPageService.findApplicationPages(appId, null, branchName, mode))
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, ApplicationPagesDTO.class))
|
||||
.cache();
|
||||
|
||||
/* Get current theme */
|
||||
Mono<ResponseDTO<Theme>> applicationThemeResponseDTOMono = applicationIdMonoCache
|
||||
.flatMap(appId -> themeService.getApplicationTheme(appId, mode, branchName))
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, Theme.class));
|
||||
|
||||
/* Get all themes */
|
||||
Mono<ResponseDTO<List>> ThemesListResponseDTOMono = applicationIdMonoCache
|
||||
.flatMap(appId ->
|
||||
themeService.getApplicationThemes(appId, branchName).collectList())
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class));
|
||||
|
||||
/* Get all custom JS libraries installed in the application */
|
||||
Mono<ResponseDTO<List>> allJSLibsInContextDTOResponseDTOMono = applicationIdMonoCache
|
||||
.flatMap(appId -> customJSLibService.getAllJSLibsInContext(
|
||||
appId, CreatorContextType.APPLICATION, branchName, isViewMode))
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class));
|
||||
|
||||
/* Check if release_server_dsl_migrations_enabled flag is true for the user */
|
||||
Mono<Boolean> migrateDslMonoCache = featureFlagsForCurrentUserResponseDTOMonoCache
|
||||
.map(ResponseDTO::getData)
|
||||
.map(flagsMap -> {
|
||||
if (!flagsMap.containsKey(FEATURE_FLAG_RELEASE_SERVER_DSL_MIGRATIONS_ENABLED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Boolean) flagsMap.get(FEATURE_FLAG_RELEASE_SERVER_DSL_MIGRATIONS_ENABLED);
|
||||
})
|
||||
.cache();
|
||||
|
||||
Mono<ResponseDTO<PageDTO>> currentPageDTOResponseDTOMono = Mono.empty();
|
||||
if (!isBlank(defaultPageId)) {
|
||||
/* Get current page */
|
||||
currentPageDTOResponseDTOMono = migrateDslMonoCache
|
||||
.flatMap(migrateDsl -> applicationPageService.getPageAndMigrateDslByBranchAndDefaultPageId(
|
||||
defaultPageId, branchName, isViewMode, migrateDsl))
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, PageDTO.class));
|
||||
}
|
||||
|
||||
/* Fetch view specific data */
|
||||
if (isViewMode) {
|
||||
/* Get list of all actions in view mode */
|
||||
Mono<ResponseDTO<List>> listOfActionViewResponseDTOMono = applicationIdMonoCache
|
||||
.flatMap(appId -> newActionService
|
||||
.getActionsForViewMode(appId, branchName)
|
||||
.collectList())
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class));
|
||||
|
||||
/* Get list of all action collections in view mode */
|
||||
Mono<ResponseDTO<List>> listOfActionCollectionViewResponseDTOMono = applicationIdMonoCache
|
||||
.flatMap(appId -> actionCollectionService
|
||||
.getActionCollectionsForViewMode(appId, branchName)
|
||||
.collectList())
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class));
|
||||
|
||||
/* This list contains the Mono objects corresponding to all the data points required for view mode. All
|
||||
* the Mono objects in this list will be evaluated via Mono.zip operator.
|
||||
*/
|
||||
List<Mono<?>> listOfMonoForPublishedApp = new ArrayList<>(List.of(
|
||||
userProfileDTOResponseDTOMono,
|
||||
tenantResponseDTOMono,
|
||||
featureFlagsForCurrentUserResponseDTOMonoCache,
|
||||
applicationPagesDTOResponseDTOMonoCache,
|
||||
applicationThemeResponseDTOMono,
|
||||
ThemesListResponseDTOMono,
|
||||
listOfActionViewResponseDTOMono,
|
||||
listOfActionCollectionViewResponseDTOMono,
|
||||
allJSLibsInContextDTOResponseDTOMono,
|
||||
productAlertResponseDTOMono));
|
||||
|
||||
if (!isBlank(defaultPageId)) {
|
||||
listOfMonoForPublishedApp.add(currentPageDTOResponseDTOMono);
|
||||
}
|
||||
|
||||
return Mono.zip(listOfMonoForPublishedApp, responseArray -> {
|
||||
consolidatedAPIResponseDTO.setV1UsersMeResp((ResponseDTO<UserProfileDTO>) responseArray[0]);
|
||||
consolidatedAPIResponseDTO.setV1TenantsCurrentResp((ResponseDTO<Tenant>) responseArray[1]);
|
||||
consolidatedAPIResponseDTO.setV1UsersFeaturesResp((ResponseDTO<Map<String, Boolean>>) responseArray[2]);
|
||||
consolidatedAPIResponseDTO.setV1PagesResp((ResponseDTO<ApplicationPagesDTO>) responseArray[3]);
|
||||
consolidatedAPIResponseDTO.setV1ThemesApplicationCurrentModeResp((ResponseDTO<Theme>) responseArray[4]);
|
||||
consolidatedAPIResponseDTO.setV1ThemesResp((ResponseDTO<List<Theme>>) responseArray[5]);
|
||||
consolidatedAPIResponseDTO.setV1ActionsViewResp((ResponseDTO<List<ActionViewDTO>>) responseArray[6]);
|
||||
consolidatedAPIResponseDTO.setV1CollectionsActionsViewResp(
|
||||
(ResponseDTO<List<ActionCollectionViewDTO>>) responseArray[7]);
|
||||
consolidatedAPIResponseDTO.setV1LibrariesApplicationResp(
|
||||
(ResponseDTO<List<CustomJSLib>>) responseArray[8]);
|
||||
consolidatedAPIResponseDTO.setV1ProductAlertResp(
|
||||
(ResponseDTO<ProductAlertResponseDTO>) responseArray[9]);
|
||||
|
||||
if (!isBlank(defaultPageId)) {
|
||||
consolidatedAPIResponseDTO.setV1PublishedPageResp((ResponseDTO<PageDTO>) responseArray[10]);
|
||||
}
|
||||
|
||||
return consolidatedAPIResponseDTO;
|
||||
});
|
||||
} else {
|
||||
/* Get all actions in edit mode */
|
||||
Mono<ResponseDTO<List>> listOfActionResponseDTOMono = applicationIdMonoCache
|
||||
.flatMap(appId -> {
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
||||
params.add(APPLICATION_ID, appId);
|
||||
return newActionService
|
||||
.getUnpublishedActions(params, branchName, false)
|
||||
.collectList();
|
||||
})
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class));
|
||||
|
||||
/* Get all action collections in edit mode */
|
||||
Mono<ResponseDTO<List>> listOfActionCollectionResponseDTOMono = applicationIdMonoCache.flatMap(appId -> {
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
||||
params.add(APPLICATION_ID, appId);
|
||||
return actionCollectionService
|
||||
.getPopulatedActionCollectionsByViewMode(params, false, branchName)
|
||||
.collectList()
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class));
|
||||
});
|
||||
|
||||
/* Get all pages in edit mode post apply migrate DSL changes */
|
||||
Mono<ResponseDTO<List>> listOfAllPageResponseDTOMono = migrateDslMonoCache
|
||||
.flatMap(migrateDsl -> applicationPagesDTOResponseDTOMonoCache
|
||||
.map(ResponseDTO::getData)
|
||||
.map(ApplicationPagesDTO::getPages)
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.flatMap(page -> applicationPageService.getPageAndMigrateDslByBranchAndDefaultPageId(
|
||||
page.getDefaultPageId(), branchName, false, migrateDsl))
|
||||
.collect(Collectors.toList()))
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class));
|
||||
|
||||
/* Get all workspace id */
|
||||
Mono<String> workspaceIdMonoCache = applicationPagesDTOResponseDTOMonoCache
|
||||
.map(ResponseDTO::getData)
|
||||
.map(ApplicationPagesDTO::getWorkspaceId)
|
||||
.cache();
|
||||
|
||||
/* Get all plugins in workspace */
|
||||
Mono<ResponseDTO<List>> listOfPluginsResponseDTOMonoCache = workspaceIdMonoCache
|
||||
.flatMap(workspaceId -> {
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
||||
params.add(WORKSPACE_ID, workspaceId);
|
||||
return pluginService.get(params).collectList();
|
||||
})
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class))
|
||||
.cache();
|
||||
|
||||
/* Get all datasources in workspace */
|
||||
Mono<ResponseDTO<List>> listOfDatasourcesResponseDTOMonoCache = workspaceIdMonoCache
|
||||
.flatMap(workspaceId -> {
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
||||
params.add(WORKSPACE_ID, workspaceId);
|
||||
return datasourceService.getAllWithStorages(params).collectList();
|
||||
})
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class))
|
||||
.cache();
|
||||
|
||||
/* Get form config for all relevant plugins by following this rule:
|
||||
* (a) there is at least one datasource of the plugin type alive in the workspace
|
||||
* (b) include REST API and GraphQL API plugin always
|
||||
* (c) ignore any other plugin
|
||||
* */
|
||||
Mono<ResponseDTO<Map>> listOfFormConfigsResponseDTOMono = Mono.zip(
|
||||
listOfPluginsResponseDTOMonoCache, listOfDatasourcesResponseDTOMonoCache)
|
||||
.map(tuple2 -> {
|
||||
Set<String> setOfAllPluginIdsToGetFormConfig = new HashSet<>();
|
||||
List<Plugin> pluginList = tuple2.getT1().getData();
|
||||
List<Datasource> datasourcesList = tuple2.getT2().getData();
|
||||
|
||||
datasourcesList.stream()
|
||||
.filter(datasource -> !isBlank(datasource.getPluginId()))
|
||||
.forEach(datasource -> setOfAllPluginIdsToGetFormConfig.add(datasource.getPluginId()));
|
||||
|
||||
pluginList.stream()
|
||||
.filter(plugin -> REST_API_PLUGIN.equals(plugin.getPackageName())
|
||||
|| GRAPHQL_PLUGIN.equals(plugin.getPackageName()))
|
||||
.forEach(plugin -> setOfAllPluginIdsToGetFormConfig.add(plugin.getId()));
|
||||
|
||||
return setOfAllPluginIdsToGetFormConfig;
|
||||
})
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.flatMap(pluginId ->
|
||||
pluginService.getFormConfig(pluginId).map(formConfig -> Pair.of(pluginId, formConfig)))
|
||||
.collectList()
|
||||
.map(listOfFormConfig -> {
|
||||
Map<String, Map> pluginIdToFormConfigMap = new HashMap<>();
|
||||
listOfFormConfig.stream().forEach(individualConfigMap -> {
|
||||
String pluginId = individualConfigMap.getFirst();
|
||||
Map config = individualConfigMap.getSecond();
|
||||
pluginIdToFormConfigMap.put(pluginId, config);
|
||||
});
|
||||
|
||||
return pluginIdToFormConfigMap;
|
||||
})
|
||||
.map(res -> (Map) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, Map.class));
|
||||
|
||||
/* List of mock datasources available to the user */
|
||||
Mono<ResponseDTO<List>> mockDataListResponseDTOMono = mockDataService
|
||||
.getMockDataSet()
|
||||
.map(MockDataDTO::getMockdbs)
|
||||
.map(res -> (List) res)
|
||||
.map(this::getSuccessResponse)
|
||||
.onErrorResume(error -> getErrorResponseMono(error, List.class));
|
||||
|
||||
/* This list contains the Mono objects corresponding to all the data points required for edit mode. All
|
||||
* the Mono objects in this list will be evaluated via Mono.zip operator
|
||||
*/
|
||||
List<Mono<?>> listOfMonoForEditMode = new ArrayList<>(List.of(
|
||||
userProfileDTOResponseDTOMono,
|
||||
tenantResponseDTOMono,
|
||||
featureFlagsForCurrentUserResponseDTOMonoCache,
|
||||
applicationPagesDTOResponseDTOMonoCache,
|
||||
applicationThemeResponseDTOMono,
|
||||
ThemesListResponseDTOMono,
|
||||
allJSLibsInContextDTOResponseDTOMono,
|
||||
productAlertResponseDTOMono,
|
||||
listOfActionResponseDTOMono,
|
||||
listOfActionCollectionResponseDTOMono,
|
||||
listOfAllPageResponseDTOMono,
|
||||
listOfPluginsResponseDTOMonoCache,
|
||||
listOfDatasourcesResponseDTOMonoCache,
|
||||
listOfFormConfigsResponseDTOMono,
|
||||
mockDataListResponseDTOMono));
|
||||
|
||||
if (!isBlank(defaultPageId)) {
|
||||
listOfMonoForEditMode.add(currentPageDTOResponseDTOMono);
|
||||
}
|
||||
|
||||
return Mono.zip(listOfMonoForEditMode, responseArray -> {
|
||||
consolidatedAPIResponseDTO.setV1UsersMeResp((ResponseDTO<UserProfileDTO>) responseArray[0]);
|
||||
consolidatedAPIResponseDTO.setV1TenantsCurrentResp((ResponseDTO<Tenant>) responseArray[1]);
|
||||
consolidatedAPIResponseDTO.setV1UsersFeaturesResp((ResponseDTO<Map<String, Boolean>>) responseArray[2]);
|
||||
consolidatedAPIResponseDTO.setV1PagesResp((ResponseDTO<ApplicationPagesDTO>) responseArray[3]);
|
||||
consolidatedAPIResponseDTO.setV1ThemesApplicationCurrentModeResp((ResponseDTO<Theme>) responseArray[4]);
|
||||
consolidatedAPIResponseDTO.setV1ThemesResp((ResponseDTO<List<Theme>>) responseArray[5]);
|
||||
consolidatedAPIResponseDTO.setV1LibrariesApplicationResp(
|
||||
(ResponseDTO<List<CustomJSLib>>) responseArray[6]);
|
||||
consolidatedAPIResponseDTO.setV1ProductAlertResp(
|
||||
(ResponseDTO<ProductAlertResponseDTO>) responseArray[7]);
|
||||
consolidatedAPIResponseDTO.setV1ActionsResp((ResponseDTO<List<ActionDTO>>) responseArray[8]);
|
||||
consolidatedAPIResponseDTO.setV1CollectionsActionsResp(
|
||||
(ResponseDTO<List<ActionCollectionDTO>>) responseArray[9]);
|
||||
consolidatedAPIResponseDTO.setV1PageDSLs((ResponseDTO<List<PageDTO>>) responseArray[10]);
|
||||
consolidatedAPIResponseDTO.setV1PluginsResp((ResponseDTO<List<Plugin>>) responseArray[11]);
|
||||
consolidatedAPIResponseDTO.setV1DatasourcesResp((ResponseDTO<List<Datasource>>) responseArray[12]);
|
||||
consolidatedAPIResponseDTO.setV1PluginFormConfigsResp(
|
||||
(ResponseDTO<Map<String, Map>>) responseArray[13]);
|
||||
consolidatedAPIResponseDTO.setV1DatasourcesMockResp((ResponseDTO<List<MockDataSet>>) responseArray[14]);
|
||||
|
||||
if (!isBlank(defaultPageId)) {
|
||||
consolidatedAPIResponseDTO.setV1PageResp((ResponseDTO<PageDTO>) responseArray[15]);
|
||||
}
|
||||
|
||||
return consolidatedAPIResponseDTO;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -163,7 +163,7 @@ public class DatasourceContextServiceCEImpl implements DatasourceContextServiceC
|
|||
public boolean shouldCacheContextForThisPlugin(Plugin plugin) {
|
||||
// !(a || b) => (!a) & (!b)
|
||||
return !PluginConstants.PackageName.REST_API_PLUGIN.equals(plugin.getPackageName())
|
||||
&& !PluginConstants.PackageName.GRAPH_QL_PLUGIN.equals(plugin.getPackageName());
|
||||
&& !PluginConstants.PackageName.GRAPHQL_PLUGIN.equals(plugin.getPackageName());
|
||||
}
|
||||
|
||||
public Mono<Object> updateDatasourceAndSetAuthentication(Object connection, DatasourceStorage datasourceStorage) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,614 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import com.appsmith.external.models.ActionDTO;
|
||||
import com.appsmith.external.models.Datasource;
|
||||
import com.appsmith.server.actioncollections.base.ActionCollectionService;
|
||||
import com.appsmith.server.applications.base.ApplicationService;
|
||||
import com.appsmith.server.datasources.base.DatasourceService;
|
||||
import com.appsmith.server.domains.ApplicationMode;
|
||||
import com.appsmith.server.domains.CustomJSLib;
|
||||
import com.appsmith.server.domains.Plugin;
|
||||
import com.appsmith.server.domains.Tenant;
|
||||
import com.appsmith.server.domains.Theme;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.dtos.ActionCollectionDTO;
|
||||
import com.appsmith.server.dtos.ActionCollectionViewDTO;
|
||||
import com.appsmith.server.dtos.ActionViewDTO;
|
||||
import com.appsmith.server.dtos.ApplicationPagesDTO;
|
||||
import com.appsmith.server.dtos.ConsolidatedAPIResponseDTO;
|
||||
import com.appsmith.server.dtos.MockDataDTO;
|
||||
import com.appsmith.server.dtos.MockDataSet;
|
||||
import com.appsmith.server.dtos.PageDTO;
|
||||
import com.appsmith.server.dtos.PageNameIdDTO;
|
||||
import com.appsmith.server.dtos.ProductAlertResponseDTO;
|
||||
import com.appsmith.server.dtos.UserProfileDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.jslibs.base.CustomJSLibService;
|
||||
import com.appsmith.server.newactions.base.NewActionService;
|
||||
import com.appsmith.server.newpages.base.NewPageService;
|
||||
import com.appsmith.server.plugins.base.PluginService;
|
||||
import com.appsmith.server.themes.base.ThemeService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
@SpringBootTest
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class ConsolidatedAPIServiceImplTest {
|
||||
|
||||
@SpyBean
|
||||
ConsolidatedAPIService consolidatedAPIService;
|
||||
|
||||
@SpyBean
|
||||
SessionUserService sessionUserService;
|
||||
|
||||
@SpyBean
|
||||
UserService userService;
|
||||
|
||||
@SpyBean
|
||||
UserDataService userDataService;
|
||||
|
||||
@SpyBean
|
||||
TenantService tenantService;
|
||||
|
||||
@SpyBean
|
||||
ProductAlertService productAlertService;
|
||||
|
||||
@SpyBean
|
||||
NewPageService newPageService;
|
||||
|
||||
@SpyBean
|
||||
NewActionService newActionService;
|
||||
|
||||
@SpyBean
|
||||
ActionCollectionService actionCollectionService;
|
||||
|
||||
@SpyBean
|
||||
ThemeService themeService;
|
||||
|
||||
@SpyBean
|
||||
ApplicationPageService applicationPageService;
|
||||
|
||||
@SpyBean
|
||||
CustomJSLibService customJSLibService;
|
||||
|
||||
@SpyBean
|
||||
PluginService pluginService;
|
||||
|
||||
@SpyBean
|
||||
ApplicationService applicationService;
|
||||
|
||||
@SpyBean
|
||||
DatasourceService datasourceService;
|
||||
|
||||
@SpyBean
|
||||
MockDataService mockDataService;
|
||||
|
||||
@Test
|
||||
public void testErrorWhenModeIsNullAndPageIdAvailable() {
|
||||
Mono<ConsolidatedAPIResponseDTO> consolidatedInfoForPageLoad =
|
||||
consolidatedAPIService.getConsolidatedInfoForPageLoad("pageId", null, null, null);
|
||||
StepVerifier.create(consolidatedInfoForPageLoad).verifyErrorSatisfies(error -> {
|
||||
assertTrue(error instanceof AppsmithException);
|
||||
assertEquals("Please enter a valid parameter appMode.", error.getMessage());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPageLoadResponseWhenPageIdAndApplicationIdMissing() {
|
||||
User sampleUser = new User();
|
||||
doReturn(Mono.just(sampleUser)).when(sessionUserService).getCurrentUser();
|
||||
|
||||
UserProfileDTO sampleUserProfileDTO = new UserProfileDTO();
|
||||
sampleUserProfileDTO.setName("sampleUserProfileDTO");
|
||||
doReturn(Mono.just(sampleUserProfileDTO)).when(userService).buildUserProfileDTO(any());
|
||||
|
||||
Map<String, Boolean> sampleFeatureFlagMap = new HashMap<>();
|
||||
sampleFeatureFlagMap.put("sampleFeatureFlag", true);
|
||||
doReturn(Mono.just(sampleFeatureFlagMap)).when(userDataService).getFeatureFlagsForCurrentUser();
|
||||
|
||||
Tenant sampleTenant = new Tenant();
|
||||
sampleTenant.setDisplayName("sampleTenant");
|
||||
doReturn(Mono.just(sampleTenant)).when(tenantService).getTenantConfiguration();
|
||||
|
||||
ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO();
|
||||
sampleProductAlertResponseDTO.setTitle("sampleProductAlert");
|
||||
doReturn(Mono.just(List.of(sampleProductAlertResponseDTO)))
|
||||
.when(productAlertService)
|
||||
.getSingleApplicableMessage();
|
||||
|
||||
Mono<ConsolidatedAPIResponseDTO> consolidatedInfoForPageLoad =
|
||||
consolidatedAPIService.getConsolidatedInfoForPageLoad(
|
||||
"pageId", "appId", "branch", ApplicationMode.PUBLISHED);
|
||||
StepVerifier.create(consolidatedInfoForPageLoad)
|
||||
.assertNext(consolidatedAPIResponseDTO -> {
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1UsersMeResp());
|
||||
assertEquals(
|
||||
"sampleUserProfileDTO",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1UsersMeResp()
|
||||
.getData()
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1TenantsCurrentResp());
|
||||
assertEquals(
|
||||
"sampleTenant",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1TenantsCurrentResp()
|
||||
.getData()
|
||||
.getDisplayName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1UsersFeaturesResp());
|
||||
assertTrue(consolidatedAPIResponseDTO
|
||||
.getV1UsersFeaturesResp()
|
||||
.getData()
|
||||
.get("sampleFeatureFlag"));
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1ProductAlertResp());
|
||||
assertEquals(
|
||||
"sampleProductAlert",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ProductAlertResp()
|
||||
.getData()
|
||||
.getTitle());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPageLoadResponseForViewMode() {
|
||||
User sampleUser = new User();
|
||||
doReturn(Mono.just(sampleUser)).when(sessionUserService).getCurrentUser();
|
||||
|
||||
UserProfileDTO sampleUserProfileDTO = new UserProfileDTO();
|
||||
sampleUserProfileDTO.setName("sampleUserProfileDTO");
|
||||
doReturn(Mono.just(sampleUserProfileDTO)).when(userService).buildUserProfileDTO(any());
|
||||
|
||||
Map<String, Boolean> sampleFeatureFlagMap = new HashMap<>();
|
||||
sampleFeatureFlagMap.put("sampleFeatureFlag", true);
|
||||
doReturn(Mono.just(sampleFeatureFlagMap)).when(userDataService).getFeatureFlagsForCurrentUser();
|
||||
|
||||
Tenant sampleTenant = new Tenant();
|
||||
sampleTenant.setDisplayName("sampleTenant");
|
||||
doReturn(Mono.just(sampleTenant)).when(tenantService).getTenantConfiguration();
|
||||
|
||||
ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO();
|
||||
sampleProductAlertResponseDTO.setTitle("sampleProductAlert");
|
||||
doReturn(Mono.just(List.of(sampleProductAlertResponseDTO)))
|
||||
.when(productAlertService)
|
||||
.getSingleApplicableMessage();
|
||||
|
||||
ApplicationPagesDTO sampleApplicationPagesDTO = new ApplicationPagesDTO();
|
||||
sampleApplicationPagesDTO.setWorkspaceId("sampleWorkspaceId");
|
||||
doReturn(Mono.just(sampleApplicationPagesDTO))
|
||||
.when(newPageService)
|
||||
.findApplicationPages(anyString(), any(), anyString(), any());
|
||||
|
||||
Theme sampleTheme = new Theme();
|
||||
sampleTheme.setName("sampleTheme");
|
||||
doReturn(Mono.just(sampleTheme)).when(themeService).getApplicationTheme(anyString(), any(), anyString());
|
||||
doReturn(Flux.just(sampleTheme)).when(themeService).getApplicationThemes(anyString(), anyString());
|
||||
|
||||
CustomJSLib sampleCustomJSLib = new CustomJSLib();
|
||||
sampleCustomJSLib.setName("sampleJSLib");
|
||||
doReturn(Mono.just(List.of(sampleCustomJSLib)))
|
||||
.when(customJSLibService)
|
||||
.getAllJSLibsInContext(anyString(), any(), anyString(), anyBoolean());
|
||||
|
||||
PageDTO samplePageDTO = new PageDTO();
|
||||
samplePageDTO.setName("samplePageDTO");
|
||||
doReturn(Mono.just(samplePageDTO))
|
||||
.when(applicationPageService)
|
||||
.getPageAndMigrateDslByBranchAndDefaultPageId(anyString(), anyString(), anyBoolean(), anyBoolean());
|
||||
|
||||
ActionViewDTO sampleActionViewDTO = new ActionViewDTO();
|
||||
sampleActionViewDTO.setName("sampleActionViewDTO");
|
||||
doReturn(Flux.just(sampleActionViewDTO)).when(newActionService).getActionsForViewMode(anyString(), anyString());
|
||||
|
||||
ActionCollectionViewDTO sampleActionCollectionViewDTO = new ActionCollectionViewDTO();
|
||||
sampleActionCollectionViewDTO.setName("sampleActionCollectionViewDTO");
|
||||
doReturn(Flux.just(sampleActionCollectionViewDTO))
|
||||
.when(actionCollectionService)
|
||||
.getActionCollectionsForViewMode(anyString(), anyString());
|
||||
|
||||
Mono<ConsolidatedAPIResponseDTO> consolidatedInfoForPageLoad =
|
||||
consolidatedAPIService.getConsolidatedInfoForPageLoad(
|
||||
"pageId", "appId", "branch", ApplicationMode.PUBLISHED);
|
||||
StepVerifier.create(consolidatedInfoForPageLoad)
|
||||
.assertNext(consolidatedAPIResponseDTO -> {
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1ActionsViewResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ActionsViewResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"sampleActionViewDTO",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ActionsViewResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1UsersMeResp());
|
||||
assertEquals(
|
||||
"sampleUserProfileDTO",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1UsersMeResp()
|
||||
.getData()
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1TenantsCurrentResp());
|
||||
assertEquals(
|
||||
"sampleTenant",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1TenantsCurrentResp()
|
||||
.getData()
|
||||
.getDisplayName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1UsersFeaturesResp());
|
||||
assertTrue(consolidatedAPIResponseDTO
|
||||
.getV1UsersFeaturesResp()
|
||||
.getData()
|
||||
.get("sampleFeatureFlag"));
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1PagesResp());
|
||||
assertEquals(
|
||||
"sampleWorkspaceId",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1PagesResp()
|
||||
.getData()
|
||||
.getWorkspaceId());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1ThemesApplicationCurrentModeResp());
|
||||
assertEquals(
|
||||
"sampleTheme",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ThemesApplicationCurrentModeResp()
|
||||
.getData()
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1ThemesResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ThemesResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"sampleTheme",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ThemesResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1CollectionsActionsViewResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1CollectionsActionsViewResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"sampleActionCollectionViewDTO",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1CollectionsActionsViewResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1PublishedPageResp());
|
||||
assertEquals(
|
||||
"samplePageDTO",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1PublishedPageResp()
|
||||
.getData()
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1LibrariesApplicationResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1LibrariesApplicationResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"sampleJSLib",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1LibrariesApplicationResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1ProductAlertResp());
|
||||
assertEquals(
|
||||
"sampleProductAlert",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ProductAlertResp()
|
||||
.getData()
|
||||
.getTitle());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPageLoadResponseForEditMode() {
|
||||
User sampleUser = new User();
|
||||
doReturn(Mono.just(sampleUser)).when(sessionUserService).getCurrentUser();
|
||||
|
||||
UserProfileDTO sampleUserProfileDTO = new UserProfileDTO();
|
||||
sampleUserProfileDTO.setName("sampleUserProfileDTO");
|
||||
doReturn(Mono.just(sampleUserProfileDTO)).when(userService).buildUserProfileDTO(any());
|
||||
|
||||
Map<String, Boolean> sampleFeatureFlagMap = new HashMap<>();
|
||||
sampleFeatureFlagMap.put("sampleFeatureFlag", true);
|
||||
doReturn(Mono.just(sampleFeatureFlagMap)).when(userDataService).getFeatureFlagsForCurrentUser();
|
||||
|
||||
Tenant sampleTenant = new Tenant();
|
||||
sampleTenant.setDisplayName("sampleTenant");
|
||||
doReturn(Mono.just(sampleTenant)).when(tenantService).getTenantConfiguration();
|
||||
|
||||
ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO();
|
||||
sampleProductAlertResponseDTO.setTitle("sampleProductAlert");
|
||||
doReturn(Mono.just(List.of(sampleProductAlertResponseDTO)))
|
||||
.when(productAlertService)
|
||||
.getSingleApplicableMessage();
|
||||
|
||||
ApplicationPagesDTO sampleApplicationPagesDTO = new ApplicationPagesDTO();
|
||||
sampleApplicationPagesDTO.setWorkspaceId("sampleWorkspaceId");
|
||||
doReturn(Mono.just(sampleApplicationPagesDTO))
|
||||
.when(newPageService)
|
||||
.findApplicationPages(anyString(), any(), anyString(), any());
|
||||
|
||||
Theme sampleTheme = new Theme();
|
||||
sampleTheme.setName("sampleTheme");
|
||||
doReturn(Mono.just(sampleTheme)).when(themeService).getApplicationTheme(anyString(), any(), anyString());
|
||||
doReturn(Flux.just(sampleTheme)).when(themeService).getApplicationThemes(anyString(), anyString());
|
||||
|
||||
CustomJSLib sampleCustomJSLib = new CustomJSLib();
|
||||
sampleCustomJSLib.setName("sampleJSLib");
|
||||
doReturn(Mono.just(List.of(sampleCustomJSLib)))
|
||||
.when(customJSLibService)
|
||||
.getAllJSLibsInContext(anyString(), any(), anyString(), anyBoolean());
|
||||
|
||||
PageDTO samplePageDTO = new PageDTO();
|
||||
samplePageDTO.setName("samplePageDTO");
|
||||
doReturn(Mono.just(samplePageDTO))
|
||||
.when(applicationPageService)
|
||||
.getPageAndMigrateDslByBranchAndDefaultPageId(anyString(), anyString(), anyBoolean(), anyBoolean());
|
||||
doReturn(Mono.just(samplePageDTO))
|
||||
.when(applicationPageService)
|
||||
.getPageAndMigrateDslByBranchAndDefaultPageId(anyString(), anyString(), anyBoolean(), anyBoolean());
|
||||
|
||||
ActionDTO sampleActionDTO = new ActionDTO();
|
||||
sampleActionDTO.setName("sampleActionDTO");
|
||||
doReturn(Flux.just(sampleActionDTO))
|
||||
.when(newActionService)
|
||||
.getUnpublishedActions(any(), anyString(), anyBoolean());
|
||||
|
||||
ActionCollectionDTO sampleActionCollectionDTO = new ActionCollectionDTO();
|
||||
sampleActionCollectionDTO.setName("sampleActionCollectionDTO");
|
||||
doReturn(Flux.just(sampleActionCollectionDTO))
|
||||
.when(actionCollectionService)
|
||||
.getPopulatedActionCollectionsByViewMode(any(), anyBoolean(), anyString());
|
||||
|
||||
PageNameIdDTO samplePageNameIdDTO = new PageNameIdDTO();
|
||||
samplePageNameIdDTO.setName("samplePageNameIdDTO");
|
||||
samplePageNameIdDTO.setDefaultPageId("pageId");
|
||||
sampleApplicationPagesDTO.setPages(List.of(samplePageNameIdDTO));
|
||||
|
||||
Plugin samplePlugin = new Plugin();
|
||||
samplePlugin.setName("samplePlugin");
|
||||
doReturn(Flux.just(samplePlugin)).when(pluginService).get(any());
|
||||
|
||||
Datasource sampleDatasource = new Datasource();
|
||||
sampleDatasource.setName("sampleDatasource");
|
||||
sampleDatasource.setPluginId("samplePluginId");
|
||||
doReturn(Flux.just(sampleDatasource)).when(datasourceService).getAllWithStorages(any());
|
||||
|
||||
Map<String, Map> sampleFormConfig = new HashMap<>();
|
||||
sampleFormConfig.put("key", Map.of());
|
||||
doReturn(Mono.just(sampleFormConfig)).when(pluginService).getFormConfig(anyString());
|
||||
|
||||
MockDataSet sampleMockDataSet = new MockDataSet();
|
||||
sampleMockDataSet.setName("sampleMockDataSet");
|
||||
MockDataDTO sampleMockDataDTO = new MockDataDTO();
|
||||
sampleMockDataDTO.setMockdbs(List.of(sampleMockDataSet));
|
||||
doReturn(Mono.just(sampleMockDataDTO)).when(mockDataService).getMockDataSet();
|
||||
|
||||
Mono<ConsolidatedAPIResponseDTO> consolidatedInfoForPageLoad =
|
||||
consolidatedAPIService.getConsolidatedInfoForPageLoad(
|
||||
"pageId", "appId", "branch", ApplicationMode.EDIT);
|
||||
StepVerifier.create(consolidatedInfoForPageLoad)
|
||||
.assertNext(consolidatedAPIResponseDTO -> {
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1UsersMeResp());
|
||||
assertEquals(
|
||||
"sampleUserProfileDTO",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1UsersMeResp()
|
||||
.getData()
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1TenantsCurrentResp());
|
||||
assertEquals(
|
||||
"sampleTenant",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1TenantsCurrentResp()
|
||||
.getData()
|
||||
.getDisplayName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1UsersFeaturesResp());
|
||||
assertTrue(consolidatedAPIResponseDTO
|
||||
.getV1UsersFeaturesResp()
|
||||
.getData()
|
||||
.get("sampleFeatureFlag"));
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1PagesResp());
|
||||
assertEquals(
|
||||
"sampleWorkspaceId",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1PagesResp()
|
||||
.getData()
|
||||
.getWorkspaceId());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1ThemesApplicationCurrentModeResp());
|
||||
assertEquals(
|
||||
"sampleTheme",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ThemesApplicationCurrentModeResp()
|
||||
.getData()
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1ThemesResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ThemesResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"sampleTheme",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ThemesResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1PagesResp());
|
||||
assertEquals(
|
||||
"sampleWorkspaceId",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1PagesResp()
|
||||
.getData()
|
||||
.getWorkspaceId());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1LibrariesApplicationResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1LibrariesApplicationResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"sampleJSLib",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1LibrariesApplicationResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1ProductAlertResp());
|
||||
assertEquals(
|
||||
"sampleProductAlert",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ProductAlertResp()
|
||||
.getData()
|
||||
.getTitle());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1ActionsResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ActionsResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"sampleActionDTO",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1ActionsResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1CollectionsActionsResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1CollectionsActionsResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"sampleActionCollectionDTO",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1CollectionsActionsResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1PageDSLs());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO.getV1PageDSLs().getData().size());
|
||||
assertEquals(
|
||||
"samplePageDTO",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1PageDSLs()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1PluginsResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1PluginsResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"samplePlugin",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1PluginsResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1PluginFormConfigsResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1PluginFormConfigsResp()
|
||||
.getData()
|
||||
.keySet()
|
||||
.size());
|
||||
assertTrue(consolidatedAPIResponseDTO
|
||||
.getV1PluginFormConfigsResp()
|
||||
.getData()
|
||||
.containsKey("samplePluginId"));
|
||||
|
||||
assertNotNull(consolidatedAPIResponseDTO.getV1DatasourcesMockResp());
|
||||
assertEquals(
|
||||
1,
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1DatasourcesMockResp()
|
||||
.getData()
|
||||
.size());
|
||||
assertEquals(
|
||||
"sampleMockDataSet",
|
||||
consolidatedAPIResponseDTO
|
||||
.getV1DatasourcesMockResp()
|
||||
.getData()
|
||||
.get(0)
|
||||
.getName());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user