From 7275865be3810c3b993e2adfcd42ec4228ed3c98 Mon Sep 17 00:00:00 2001 From: subratadeypappu Date: Wed, 4 Dec 2024 19:06:59 +0600 Subject: [PATCH] Add code split for adding package pull status indicator --- .../ce/ConsolidatedAPIServiceCEImpl.java | 334 ++++++++++-------- 1 file changed, 186 insertions(+), 148 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java index 71c417afaf18..18e0b23294e0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java @@ -106,11 +106,11 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { private final ObservationRegistry observationRegistry; private final CacheableRepositoryHelper cacheableRepositoryHelper; - ResponseDTO getSuccessResponse(T data) { + protected ResponseDTO getSuccessResponse(T data) { return new ResponseDTO<>(HttpStatus.OK.value(), data, null); } - private Mono> getErrorResponseMono(Throwable error) { + protected Mono> getErrorResponseMono(Throwable error) { if (error instanceof AppsmithException appsmithException) { return Mono.just(new ResponseDTO<>( appsmithException.getHttpStatus(), @@ -125,7 +125,7 @@ private Mono> getErrorResponseMono(Throwable error) { INTERNAL_SERVER_ERROR_STATUS, new ErrorDTO(INTERNAL_SERVER_ERROR_CODE, error.getMessage()))); } - private Mono> toResponseDTO(Mono mono) { + protected Mono> toResponseDTO(Mono mono) { return mono.map(this::getSuccessResponse).onErrorResume(this::getErrorResponseMono); } @@ -148,6 +148,18 @@ public Mono getConsolidatedInfoForPageLoad( /* This object will serve as a container to hold the response of this method*/ ConsolidatedAPIResponseDTO consolidatedAPIResponseDTO = new ConsolidatedAPIResponseDTO(); + List> fetches = + getAllFetchableMonos(consolidatedAPIResponseDTO, basePageId, baseApplicationId, branchName, mode); + + return Mono.when(fetches).thenReturn(consolidatedAPIResponseDTO); + } + + protected List> getAllFetchableMonos( + ConsolidatedAPIResponseDTO consolidatedAPIResponseDTO, + String basePageId, + String baseApplicationId, + String branchName, + ApplicationMode mode) { final List> fetches = new ArrayList<>(); /* Get user profile data */ @@ -196,163 +208,26 @@ public Mono getConsolidatedInfoForPageLoad( .tap(Micrometer.observation(observationRegistry))); if (isBlank(basePageId) && isBlank(baseApplicationId)) { - return Mono.when(fetches).thenReturn(consolidatedAPIResponseDTO); + return fetches; } /* Get view mode - EDIT or PUBLISHED */ - boolean isViewMode = ApplicationMode.PUBLISHED.equals(mode); + boolean isViewMode = isViewMode(mode); /* Fetch default application id if not provided */ if (isBlank(basePageId)) { - return Mono.when(fetches).thenReturn(consolidatedAPIResponseDTO); + return fetches; } - Mono baseApplicationIdMono = Mono.just(""); - if (isViewMode) { - // Attempt to retrieve the application ID associated with the given base page ID from the cache. - baseApplicationIdMono = cacheableRepositoryHelper - .fetchBaseApplicationId(basePageId, baseApplicationId) - .switchIfEmpty(Mono.just("")) - .cast(String.class); - } - - baseApplicationIdMono = baseApplicationIdMono - .name(getQualifiedSpanName(APPLICATION_ID_FETCH_REDIS_SPAN, mode)) - .tap(Micrometer.observation(observationRegistry)) - .cache(); - - Mono> applicationAndPageTupleMono = baseApplicationIdMono - .flatMap(cachedBaseApplicationId -> { - Mono applicationMono; - Mono branchedPageMonoCached; - - branchedPageMonoCached = newPageService - .findByBranchNameAndBasePageIdAndApplicationMode(branchName, basePageId, mode) - .cache(); - - if (StringUtils.hasText(cachedBaseApplicationId)) { - // Handle non-empty baseApplicationId - applicationMono = applicationService.findByBaseIdBranchNameAndApplicationMode( - cachedBaseApplicationId, branchName, mode); - } else { - // Handle empty or null baseApplicationId - applicationMono = branchedPageMonoCached.flatMap(branchedPage -> - // Use the application ID to find the complete application details. - applicationService - .findByBranchedApplicationIdAndApplicationMode( - branchedPage.getApplicationId(), mode) - .flatMap(application -> { - if (isViewMode) { - // Update the cache with the new application’s base ID for future - // queries. - return cacheableRepositoryHelper - .fetchBaseApplicationId(basePageId, application.getBaseId()) - .thenReturn(application) - .name(getQualifiedSpanName( - APPLICATION_ID_UPDATE_REDIS_SPAN, mode)) - .tap(Micrometer.observation(observationRegistry)); - } - return Mono.just(application); - })); - } - - if (StringUtils.hasText(branchName)) { + Mono baseApplicationIdMono = getBaseApplicationIdMono(basePageId, baseApplicationId, mode, isViewMode); - // If in case the application is a non git connected application and the branch name url param - // is present, then we must default to the app without any branches. - return applicationMono.zipWith(branchedPageMonoCached).onErrorResume(error -> { - // This situation would arise if page or application is not returned. - // here we would land on error instead of empty because both apis which are being - // called errors out on empty returns. - - log.info( - "application or page has for base pageId {} and branchName {} has not been found.", - basePageId, - branchName); - if (error instanceof AppsmithException) { - Mono basePageMono = - newPageService.findByBranchNameAndBasePageIdAndApplicationMode( - null, basePageId, mode); - - return basePageMono.flatMap(basePage -> { - if (StringUtils.hasText(basePage.getBranchName())) { - // If the branch name is present then the application is git connected - // the error should be thrown. - // TODO: verify if branch name could be residue from old git connection - // Application metadata is absolute check for the same. - return Mono.error(error); - } - - return applicationService - .findByBranchedApplicationIdAndApplicationMode( - basePage.getApplicationId(), mode) - .zipWith(basePageMono) - .map(tuple2 -> { - log.info( - "The branchName url param should not be associated with application {} as this is not a git connected application", - tuple2.getT1().getId()); - return tuple2; - }); - }); - } - - return Mono.error(error); - }); - } - - return applicationMono.zipWith(branchedPageMonoCached).flatMap(tuple2 -> { - Application application = tuple2.getT1(); - NewPage branchedPage = tuple2.getT2(); - - GitArtifactMetadata gitMetadata = application.getGitArtifactMetadata(); - - boolean isNotAGitApp = gitMetadata == null; - boolean isDefaultBranchNameAbsent = - isNotAGitApp || !StringUtils.hasText(gitMetadata.getDefaultBranchName()); - boolean isBranchDefault = !isDefaultBranchNameAbsent - && gitMetadata.getDefaultBranchName().equals(gitMetadata.getBranchName()); - - // This last check is specially for view mode, when a queried page which is not present - // in default branch, and cacheable repository refers to the base application - // from given page id. then the branched page may not belong to the base application - // hence a validation is required. - // This condition is always true for a non git app - boolean isPageFromSameApplication = application.getId().equals(branchedPage.getApplicationId()); - - if ((isNotAGitApp || isDefaultBranchNameAbsent || isBranchDefault) - && (!isViewMode || isPageFromSameApplication)) { - return applicationMono.zipWith(branchedPageMonoCached); - } - - log.info( - "ConsolidatedApi for page id {}, and application id {} has been queried without a branch url param", - branchedPage.getId(), - application.getId()); - - // The git connected application has not been queried with branch param, - // and the base branch is not same as the default branch. - // we need to find return the default branch from here. - - String defaultBranchName = gitMetadata.getDefaultBranchName(); - - return applicationService - .findByBaseIdBranchNameAndApplicationMode(application.getId(), defaultBranchName, mode) - .zipWith(newPageService.findByBranchNameAndBasePageIdAndApplicationMode( - defaultBranchName, basePageId, mode)); - }); - }) - .cache(); + Mono> applicationAndPageTupleMono = + getApplicationAndPageTupleMono(basePageId, branchName, mode, baseApplicationIdMono, isViewMode); Mono branchedPageMonoCached = applicationAndPageTupleMono.map(Tuple2::getT2).cache(); - Mono branchedApplicationMonoCached = - applicationAndPageTupleMono.map(Tuple2::getT1).cache(); - - branchedApplicationMonoCached = branchedApplicationMonoCached - .name(getQualifiedSpanName(APPLICATION_ID_SPAN, mode)) - .tap(Micrometer.observation(observationRegistry)) - .cache(); + Mono branchedApplicationMonoCached = getBranchedApplicationMono(mode, applicationAndPageTupleMono); Mono> pagesFromCurrentApplicationMonoCached = branchedApplicationMonoCached .flatMap(branchedApplication -> @@ -585,8 +460,171 @@ public Mono getConsolidatedInfoForPageLoad( .name(getQualifiedSpanName(MOCK_DATASOURCES_SPAN, mode)) .tap(Micrometer.observation(observationRegistry))); } + return fetches; + } - return Mono.when(fetches).thenReturn(consolidatedAPIResponseDTO); + protected Mono getBaseApplicationIdMono( + String basePageId, String baseApplicationId, ApplicationMode mode, boolean isViewMode) { + Mono baseApplicationIdMono = Mono.just(""); + if (isViewMode) { + // Attempt to retrieve the application ID associated with the given base page ID from the cache. + baseApplicationIdMono = cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId, baseApplicationId) + .switchIfEmpty(Mono.just("")) + .cast(String.class); + } + + baseApplicationIdMono = baseApplicationIdMono + .name(getQualifiedSpanName(APPLICATION_ID_FETCH_REDIS_SPAN, mode)) + .tap(Micrometer.observation(observationRegistry)) + .cache(); + return baseApplicationIdMono; + } + + protected boolean isViewMode(ApplicationMode mode) { + return ApplicationMode.PUBLISHED.equals(mode); + } + + protected Mono getBranchedApplicationMono( + ApplicationMode mode, Mono> applicationAndPageTupleMono) { + Mono branchedApplicationMonoCached = + applicationAndPageTupleMono.map(Tuple2::getT1).cache(); + + branchedApplicationMonoCached = branchedApplicationMonoCached + .name(getQualifiedSpanName(APPLICATION_ID_SPAN, mode)) + .tap(Micrometer.observation(observationRegistry)) + .cache(); + return branchedApplicationMonoCached; + } + + protected Mono> getApplicationAndPageTupleMono( + String basePageId, + String branchName, + ApplicationMode mode, + Mono baseApplicationIdMono, + boolean isViewMode) { + Mono> applicationAndPageTupleMono = baseApplicationIdMono + .flatMap(cachedBaseApplicationId -> { + Mono applicationMono; + Mono branchedPageMonoCached; + + branchedPageMonoCached = newPageService + .findByBranchNameAndBasePageIdAndApplicationMode(branchName, basePageId, mode) + .cache(); + + if (StringUtils.hasText(cachedBaseApplicationId)) { + // Handle non-empty baseApplicationId + applicationMono = applicationService.findByBaseIdBranchNameAndApplicationMode( + cachedBaseApplicationId, branchName, mode); + } else { + // Handle empty or null baseApplicationId + applicationMono = branchedPageMonoCached.flatMap(branchedPage -> + // Use the application ID to find the complete application details. + applicationService + .findByBranchedApplicationIdAndApplicationMode( + branchedPage.getApplicationId(), mode) + .flatMap(application -> { + if (isViewMode) { + // Update the cache with the new application’s base ID for future + // queries. + return cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId, application.getBaseId()) + .thenReturn(application) + .name(getQualifiedSpanName( + APPLICATION_ID_UPDATE_REDIS_SPAN, mode)) + .tap(Micrometer.observation(observationRegistry)); + } + return Mono.just(application); + })); + } + + if (StringUtils.hasText(branchName)) { + + // If in case the application is a non git connected application and the branch name url param + // is present, then we must default to the app without any branches. + return applicationMono.zipWith(branchedPageMonoCached).onErrorResume(error -> { + // This situation would arise if page or application is not returned. + // here we would land on error instead of empty because both apis which are being + // called errors out on empty returns. + + log.info( + "application or page has for base pageId {} and branchName {} has not been found.", + basePageId, + branchName); + if (error instanceof AppsmithException) { + Mono basePageMono = + newPageService.findByBranchNameAndBasePageIdAndApplicationMode( + null, basePageId, mode); + + return basePageMono.flatMap(basePage -> { + if (StringUtils.hasText(basePage.getBranchName())) { + // If the branch name is present then the application is git connected + // the error should be thrown. + // TODO: verify if branch name could be residue from old git connection + // Application metadata is absolute check for the same. + return Mono.error(error); + } + + return applicationService + .findByBranchedApplicationIdAndApplicationMode( + basePage.getApplicationId(), mode) + .zipWith(basePageMono) + .map(tuple2 -> { + log.info( + "The branchName url param should not be associated with application {} as this is not a git connected application", + tuple2.getT1().getId()); + return tuple2; + }); + }); + } + + return Mono.error(error); + }); + } + + return applicationMono.zipWith(branchedPageMonoCached).flatMap(tuple2 -> { + Application application = tuple2.getT1(); + NewPage branchedPage = tuple2.getT2(); + + GitArtifactMetadata gitMetadata = application.getGitArtifactMetadata(); + + boolean isNotAGitApp = gitMetadata == null; + boolean isDefaultBranchNameAbsent = + isNotAGitApp || !StringUtils.hasText(gitMetadata.getDefaultBranchName()); + boolean isBranchDefault = !isDefaultBranchNameAbsent + && gitMetadata.getDefaultBranchName().equals(gitMetadata.getBranchName()); + + // This last check is specially for view mode, when a queried page which is not present + // in default branch, and cacheable repository refers to the base application + // from given page id. then the branched page may not belong to the base application + // hence a validation is required. + // This condition is always true for a non git app + boolean isPageFromSameApplication = application.getId().equals(branchedPage.getApplicationId()); + + if ((isNotAGitApp || isDefaultBranchNameAbsent || isBranchDefault) + && (!isViewMode || isPageFromSameApplication)) { + return applicationMono.zipWith(branchedPageMonoCached); + } + + log.info( + "ConsolidatedApi for page id {}, and application id {} has been queried without a branch url param", + branchedPage.getId(), + application.getId()); + + // The git connected application has not been queried with branch param, + // and the base branch is not same as the default branch. + // we need to find return the default branch from here. + + String defaultBranchName = gitMetadata.getDefaultBranchName(); + + return applicationService + .findByBaseIdBranchNameAndApplicationMode(application.getId(), defaultBranchName, mode) + .zipWith(newPageService.findByBranchNameAndBasePageIdAndApplicationMode( + defaultBranchName, basePageId, mode)); + }); + }) + .cache(); + return applicationAndPageTupleMono; } private boolean isPossibleToCreateQueryWithoutDatasource(Plugin plugin) {