From 6b6deaf98ffe7fbe1ad0e8239a6bbfec7cfc02a5 Mon Sep 17 00:00:00 2001 From: Nayan Date: Fri, 20 May 2022 23:42:09 +0600 Subject: [PATCH] feat: Add query count and page count as attributes to publish app event (#13847) Adds number of pages and number of queries in a Application to the list of analytics attributes when an application is published. --- .../ce/ApplicationControllerCE.java | 8 +- .../services/ce/ApplicationPageServiceCE.java | 2 - .../ce/ApplicationPageServiceCEImpl.java | 78 +++++++++---------- 3 files changed, 40 insertions(+), 48 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationControllerCE.java index 1ab2f9272f..4604265f54 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationControllerCE.java @@ -89,13 +89,7 @@ public class ApplicationControllerCE extends BaseController> publish(@PathVariable String defaultApplicationId, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { return applicationPageService.publish(defaultApplicationId, branchName, true) - .flatMap(application -> - // This event should parallel a similar event sent from the client, so we want it to be sent by the - // controller and not the service method. - applicationPageService.sendApplicationPublishedEvent(application) - // This will only be called when the publishing was successful, so we can always return `true` here. - .thenReturn(new ResponseDTO<>(HttpStatus.OK.value(), true, null)) - ); + .thenReturn(new ResponseDTO<>(HttpStatus.OK.value(), true, null)); } @PutMapping("/{defaultApplicationId}/page/{defaultPageId}/makeDefault") diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCE.java index 9582cd8b94..14aac589af 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCE.java @@ -51,8 +51,6 @@ public interface ApplicationPageServiceCE { void generateAndSetPagePolicies(Application application, PageDTO page); - Mono sendApplicationPublishedEvent(Application application); - Mono reorderPage(String applicationId, String pageId, Integer order, String branchName); Mono deleteApplicationByResource(Application application); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java index bc08f31502..b00cfa833c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java @@ -892,7 +892,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { application -> themeService.publishTheme(application.getId()) ); - Flux publishApplicationAndPages = applicationMono + Mono> publishApplicationAndPages = applicationMono //Return all the pages in the Application .flatMap(application -> { List pages = application.getPages(); @@ -952,10 +952,11 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { page.setPublishedPage(page.getUnpublishedPage()); return page; })) + .flatMap(newPageService::save) .collectList() - .flatMapMany(newPageService::saveAll); + .cache(); // caching as we'll need this to send analytics attributes after publishing the app - Flux publishedActionsFlux = newActionService + Mono> publishedActionsListMono = newActionService .findAllByApplicationIdAndViewMode(applicationId, false, MANAGE_ACTIONS, null) .flatMap(newAction -> { // If the action was deleted in edit mode, now this document can be safely archived @@ -967,10 +968,11 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { newAction.setPublishedAction(newAction.getUnpublishedAction()); return Mono.just(newAction); }) + .flatMap(newActionService::save) .collectList() - .flatMapMany(newActionService::saveAll); + .cache(); // caching as we'll need this to send analytics attributes after publishing the app - Flux publishedCollectionsFlux = actionCollectionService + Mono> publishedActionCollectionsListMono = actionCollectionService .findAllByApplicationIdAndViewMode(applicationId, false, MANAGE_ACTIONS, null) .flatMap(collection -> { // If the collection was deleted in edit mode, now this can be safely deleted from the repository @@ -982,16 +984,42 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { collection.setPublishedCollection(collection.getUnpublishedCollection()); return Mono.just(collection); }) - .collectList() - .flatMapMany(actionCollectionService::saveAll); + .flatMap(actionCollectionService::save) + .collectList(); return Mono.when( - publishApplicationAndPages.collectList(), - publishedActionsFlux.collectList(), - publishedCollectionsFlux, + publishApplicationAndPages, + publishedActionsListMono, + publishedActionCollectionsListMono, publishThemeMono ) - .then(applicationMono); + .then(sendApplicationPublishedEvent(publishApplicationAndPages, publishedActionsListMono, publishedActionCollectionsListMono, applicationId)); + } + + private Mono sendApplicationPublishedEvent(Mono> publishApplicationAndPages, + Mono> publishedActionsFlux, + Mono> publishedActionsCollectionFlux, + String applicationId) { + return Mono.zip( + publishApplicationAndPages, + publishedActionsFlux, + publishedActionsCollectionFlux, + // not using existing applicationMono because we need the latest Application after published + applicationService.findById(applicationId, MANAGE_APPLICATIONS) + ) + .flatMap(objects -> { + Application application = objects.getT4(); + Map extraProperties = new HashMap<>(); + extraProperties.put("pageCount", objects.getT1().size()); + extraProperties.put("queryCount", objects.getT2().size()); + extraProperties.put("actionCollectionCount", objects.getT3().size()); + extraProperties.put("appId", defaultIfNull(application.getId(), "")); + extraProperties.put("appName", defaultIfNull(application.getName(), "")); + extraProperties.put("orgId", defaultIfNull(application.getOrganizationId(), "")); + extraProperties.put("publishedAt", defaultIfNull(application.getLastDeployedAt(), "")); + + return analyticsService.sendObjectEvent(AnalyticsEvents.PUBLISH_APPLICATION, application, extraProperties); + }); } @Override @@ -1001,34 +1029,6 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { .map(responseUtils::updateApplicationWithDefaultResources); } - @Override - public Mono sendApplicationPublishedEvent(Application application) { - if (!analyticsService.isActive()) { - return Mono.empty(); - } - - return sessionUserService.getCurrentUser() - .flatMap(user -> { - int publishedPageCount = 0; - if(application.getPublishedPages() != null) { - publishedPageCount = application.getPublishedPages().size(); - } - - analyticsService.sendEvent( - AnalyticsEvents.PUBLISH_APPLICATION.getEventName(), - user.getUsername(), - Map.of( - "appId", defaultIfNull(application.getId(), ""), - "appName", defaultIfNull(application.getName(), ""), - "orgId", defaultIfNull(application.getOrganizationId(), ""), - "pageCount", publishedPageCount + "", - "publishedAt", defaultIfNull(application.getLastDeployedAt(), "") - ) - ); - return Mono.empty(); - }); - } - /** This function walks through all the pages and reorders them and updates the order as per the user preference. * A page can be moved up or down from the current position and accordingly the order of the remaining page changes. * @param defaultAppId The id of the Application