From 0853b38355ebd72a6c4df215cd15f3f9a7d2dac1 Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Wed, 26 Jun 2024 18:05:25 +0530 Subject: [PATCH 01/11] refactor datasource import flow to add support for dryOps queries --- .../server/constants/ce/FieldNameCE.java | 2 + .../datasources/base/DatasourceServiceCE.java | 6 ++- .../base/DatasourceServiceCEImpl.java | 53 +++++++++++++++---- .../DatasourceImportableServiceCEImpl.java | 44 ++++++++++++--- .../base/DatasourceStorageServiceCE.java | 7 ++- .../base/DatasourceStorageServiceCEImpl.java | 31 ++++++++--- .../ce/MappedImportableResourcesCE_DTO.java | 7 +++ .../ce/DatasourceContextServiceCEImpl.java | 2 +- 8 files changed, 125 insertions(+), 27 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java index 4f96dee7d21d..f11aed539049 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java @@ -202,4 +202,6 @@ public class FieldNameCE { public static final String ARTIFACT_CONTEXT = "artifactContext"; public static final String ARTIFACT_ID = "artifactId"; public static final String BODY = "body"; + + public static final String CREATE = "save"; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCE.java index fbcd04f8a106..c3ccb9508b77 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCE.java @@ -11,6 +11,7 @@ import reactor.core.publisher.Mono; import java.util.List; +import java.util.Map; import java.util.Set; public interface DatasourceServiceCE { @@ -39,6 +40,8 @@ public interface DatasourceServiceCE { Mono save(Datasource datasource); + Mono save(Datasource datasource, boolean isDryOps); + /** * Retrieves all datasources based on input params, currently only workspaceId. * The retrieved datasources will contain configuration from the default environment, @@ -63,7 +66,8 @@ public interface DatasourceServiceCE { Mono create(Datasource datasource); - Mono createWithoutPermissions(Datasource datasource); + Mono createWithoutPermissions( + Datasource datasource, Map> datasourceStorageDryRunQueries); Mono updateDatasourceStorage( DatasourceStorageDTO datasourceStorageDTO, String activeEnvironmentId, Boolean IsUserRefreshedUpdate); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java index 60738e7f7668..f4e0635cee92 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java @@ -140,16 +140,21 @@ public DatasourceServiceCEImpl( @Override public Mono create(Datasource datasource) { - return createEx(datasource, workspacePermission.getDatasourceCreatePermission()); + return createEx(datasource, workspacePermission.getDatasourceCreatePermission(), false, null); } // TODO: Check usage @Override - public Mono createWithoutPermissions(Datasource datasource) { - return createEx(datasource, null); + public Mono createWithoutPermissions( + Datasource datasource, Map> datasourceStorageDryRunQueries) { + return createEx(datasource, null, true, datasourceStorageDryRunQueries); } - private Mono createEx(@NotNull Datasource datasource, AclPermission permission) { + private Mono createEx( + @NotNull Datasource datasource, + AclPermission permission, + boolean isDryOps, + Map> datasourceStorageDryRunQueries) { // Validate incoming request String workspaceId = datasource.getWorkspaceId(); if (!hasText(workspaceId)) { @@ -193,7 +198,7 @@ private Mono createEx(@NotNull Datasource datasource, AclPermission Mono userMono = sessionUserService.getCurrentUser(); return generateAndSetDatasourcePolicies(userMono, datasource1, permission); }) - .flatMap(this::validateAndSaveDatasourceToRepository) + .flatMap(datasourceInDb -> validateAndSaveDatasourceToRepository(datasourceInDb, isDryOps)) .flatMap(savedDatasource -> analyticsService.sendCreateEvent(savedDatasource, getAnalyticsProperties(savedDatasource))); } else { @@ -217,7 +222,18 @@ private Mono createEx(@NotNull Datasource datasource, AclPermission return Mono.just(datasourceStorage); } - return datasourceStorageService.create(datasourceStorage); + return datasourceStorageService + .create(datasourceStorage, true) + .map(datasourceStorage1 -> { + if (datasourceStorageDryRunQueries.containsKey(FieldName.CREATE)) { + datasourceStorageDryRunQueries + .get(FieldName.CREATE) + .add(datasourceStorage1); + } else { + datasourceStorageDryRunQueries.put(FieldName.CREATE, List.of(datasourceStorage1)); + } + return datasourceStorage1; + }); }) .map(datasourceStorageService::createDatasourceStorageDTOFromDatasourceStorage) .collectMap(DatasourceStorageDTO::getEnvironmentId) @@ -303,7 +319,7 @@ public Mono updateDatasource( copyNestedNonNullProperties(datasource, datasourceInDb); return datasourceInDb; }) - .flatMap(this::validateAndSaveDatasourceToRepository) + .flatMap(datasourceInDb -> validateAndSaveDatasourceToRepository(datasourceInDb, false)) .map(savedDatasource -> { // not required by client side in order to avoid updating it to a null storage, // one alternative is that we find and send datasourceStorages along, but that is an expensive call @@ -355,7 +371,7 @@ public Mono updateDatasourceStorage( datasourceStorage.prepareTransientFields(dbDatasource); return datasourceStorageService - .updateDatasourceStorage(datasourceStorage, activeEnvironmentId, Boolean.TRUE) + .updateDatasourceStorage(datasourceStorage, activeEnvironmentId, Boolean.TRUE, false) .map(datasourceStorageService::createDatasourceStorageDTOFromDatasourceStorage) .map(datasourceStorageDTO1 -> { dbDatasource.getDatasourceStorages().put(trueEnvironmentId, datasourceStorageDTO1); @@ -373,12 +389,29 @@ public Mono save(Datasource datasource) { return repository.save(datasource); } - private Mono validateAndSaveDatasourceToRepository(Datasource datasource) { + @Override + public Mono save(Datasource datasource, boolean isDryOps) { + if (datasource.getGitSyncId() == null) { + datasource.setGitSyncId( + datasource.getWorkspaceId() + "_" + Instant.now().toString()); + } + datasource.updateForBulkWriteOperation(); + return Mono.just(datasource); + } + + private Mono validateAndSaveDatasourceToRepository(Datasource datasource, boolean isDryOps) { return Mono.just(datasource) .flatMap(this::validateDatasource) .flatMap(unsavedDatasource -> { - return repository.save(unsavedDatasource).map(savedDatasource -> { + Mono datasourceMono; + if (isDryOps) { + unsavedDatasource.updateForBulkWriteOperation(); + datasourceMono = Mono.just(unsavedDatasource); + } else { + datasourceMono = repository.save(unsavedDatasource); + } + return datasourceMono.map(savedDatasource -> { // datasource.pluginName is a transient field. It was set by validateDatasource method // object from db will have pluginName=null so set it manually from the unsaved datasource obj savedDatasource.setPluginName(unsavedDatasource.getPluginName()); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java index c4115be2bee0..241126423145 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java @@ -211,9 +211,16 @@ private Mono> importDatasources( // Don't update the datasource configuration for already available datasources existingDatasource.setDatasourceConfiguration(null); return datasourceService - .save(existingDatasource) - .map(createdDatasource -> - Tuples.of(createdDatasource.getName(), createdDatasource.getId())); + .save(existingDatasource, true) + .map(createdDatasource -> { + // Add dry run queries for the datasource + addDryOpsForEntity( + FieldName.CREATE, + mappedImportableResourcesDTO.getDatasourceDryRunQueries(), + createdDatasource); + return Tuples.of( + createdDatasource.getName(), createdDatasource.getId()); + }); } else { // This is explicitly copied over from the map we created before datasourceStorage.setPluginId(pluginMap.get(datasourceStorage.getPluginId())); @@ -235,9 +242,16 @@ private Mono> importDatasources( datasourceStorage, workspace, environmentId, - importingMetaDTO.getPermissionProvider()) - .map(createdDatasource -> - Tuples.of(importedDatasourceName, createdDatasource.getId())); + importingMetaDTO.getPermissionProvider(), + mappedImportableResourcesDTO) + .map(createdDatasource -> { + // Add dry run queries for the datasource + addDryOpsForEntity( + FieldName.CREATE, + mappedImportableResourcesDTO.getDatasourceDryRunQueries(), + createdDatasource); + return Tuples.of(importedDatasourceName, createdDatasource.getId()); + }); } }); }) @@ -266,7 +280,8 @@ private Mono createUniqueDatasourceIfNotPresent( DatasourceStorage datasourceStorage, Workspace workspace, String environmentId, - ImportArtifactPermissionProvider permissionProvider) { + ImportArtifactPermissionProvider permissionProvider, + MappedImportableResourcesDTO mappedImportableResourcesDTO) { /* 1. If same datasource is present return 2. If unable to find the datasource create a new datasource with unique name and return @@ -311,11 +326,15 @@ private Mono createUniqueDatasourceIfNotPresent( getUniqueSuffixForDuplicateNameEntity(duplicateNameDatasource, workspace.getId())) .map(dsName -> { datasourceStorage.setName(datasourceStorage.getName() + dsName); + return datasourceService.createDatasourceFromDatasourceStorage(datasourceStorage); }) .switchIfEmpty(Mono.just( datasourceService.createDatasourceFromDatasourceStorage(datasourceStorage))) - .flatMap(datasourceService::createWithoutPermissions); + // DRY RUN queries are not saved, so we need to create them separately at the import service + // solution + .flatMap(datasource -> datasourceService.createWithoutPermissions( + datasource, mappedImportableResourcesDTO.getDatasourceStorageDryRunQueries())); })) .onErrorResume(throwable -> { log.error("failed to import datasource", throwable); @@ -386,4 +405,13 @@ private Mono getUniqueSuffixForDuplicateNameEntity(BaseDomain sourceEnti public Flux getEntitiesPresentInWorkspace(String workspaceId) { return datasourceService.getAllByWorkspaceIdWithStorages(workspaceId, null); } + + private void addDryOpsForEntity( + String queryType, Map> dryRunOpsMap, Datasource createdDatasource) { + if (dryRunOpsMap.containsKey(queryType)) { + dryRunOpsMap.get(queryType).add(createdDatasource); + } else { + dryRunOpsMap.put(queryType, List.of(createdDatasource)); + } + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCE.java index 0f9966566561..4b018ba2a35a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCE.java @@ -15,6 +15,8 @@ public interface DatasourceStorageServiceCE { Mono create(DatasourceStorage datasourceStorage); + Mono create(DatasourceStorage datasourceStorage, boolean isDryOps); + Mono save(DatasourceStorage datasourceStorage); Mono archive(DatasourceStorage datasourceStorage); @@ -30,7 +32,10 @@ public interface DatasourceStorageServiceCE { Mono findStrictlyByDatasourceIdAndEnvironmentId(String datasourceId, String environmentId); Mono updateDatasourceStorage( - DatasourceStorage datasourceStorage, String activeEnvironmentId, Boolean IsUserRefreshedUpdate); + DatasourceStorage datasourceStorage, + String activeEnvironmentId, + Boolean IsUserRefreshedUpdate, + boolean isDryOps); Mono validateDatasourceStorage(DatasourceStorage datasourceStorage); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCEImpl.java index 751a7fcf2814..52a3820a088e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCEImpl.java @@ -58,7 +58,16 @@ public DatasourceStorageServiceCEImpl( @Override public Mono create(DatasourceStorage datasourceStorage) { return this.checkDuplicateDatasourceStorage(datasourceStorage) - .then(this.validateAndSaveDatasourceStorageToRepository(datasourceStorage)) + .then(validateAndSaveDatasourceStorageToRepository(datasourceStorage, false)) + .flatMap(this::populateHintMessages) // For REST API datasource create flow. + .flatMap(savedDatasourceStorage -> analyticsService.sendCreateEvent( + savedDatasourceStorage, getAnalyticsProperties(savedDatasourceStorage))); + } + + @Override + public Mono create(DatasourceStorage datasourceStorage, boolean isDryOps) { + return this.checkDuplicateDatasourceStorage(datasourceStorage) + .then(validateAndSaveDatasourceStorageToRepository(datasourceStorage, isDryOps)) .flatMap(this::populateHintMessages) // For REST API datasource create flow. .flatMap(savedDatasourceStorage -> analyticsService.sendCreateEvent( savedDatasourceStorage, getAnalyticsProperties(savedDatasourceStorage))); @@ -126,7 +135,10 @@ public Mono findStrictlyByDatasourceIdAndEnvironmentId( @Override public Mono updateDatasourceStorage( - DatasourceStorage datasourceStorage, String activeEnvironmentId, Boolean isUserRefreshedUpdate) { + DatasourceStorage datasourceStorage, + String activeEnvironmentId, + Boolean isUserRefreshedUpdate, + boolean isDryOps) { String datasourceId = datasourceStorage.getDatasourceId(); String environmentId = datasourceStorage.getEnvironmentId(); @@ -143,7 +155,8 @@ public Mono updateDatasourceStorage( } return dbStorage; }) - .flatMap(this::validateAndSaveDatasourceStorageToRepository) + .flatMap(datasourceStorage1 -> + validateAndSaveDatasourceStorageToRepository(datasourceStorage1, isDryOps)) .flatMap(savedDatasourceStorage -> { Map analyticsProperties = getAnalyticsProperties(savedDatasourceStorage); Boolean isUserInvokedUpdate = TRUE.equals(isUserRefreshedUpdate) ? TRUE : FALSE; @@ -211,14 +224,20 @@ public Mono validateDatasourceConfiguration(DatasourceStorage }); } - private Mono validateAndSaveDatasourceStorageToRepository(DatasourceStorage datasourceStorage) { + private Mono validateAndSaveDatasourceStorageToRepository( + DatasourceStorage datasourceStorage, boolean isDryOps) { return Mono.just(datasourceStorage) .map(this::sanitizeDatasourceStorage) .flatMap(datasourceStorage1 -> validateDatasourceStorage(datasourceStorage1)) .flatMap(this::executePreSaveActions) - .flatMap(unsavedDatasourceStorage -> - repository.save(unsavedDatasourceStorage).thenReturn(unsavedDatasourceStorage)); + .flatMap(unsavedDatasourceStorage -> { + if (isDryOps) { + unsavedDatasourceStorage.updateForBulkWriteOperation(); + return Mono.just(unsavedDatasourceStorage); + } + return repository.save(unsavedDatasourceStorage).thenReturn(unsavedDatasourceStorage); + }); } @Override diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/MappedImportableResourcesCE_DTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/MappedImportableResourcesCE_DTO.java index e9247ccfa658..58363cdf2ef5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/MappedImportableResourcesCE_DTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/MappedImportableResourcesCE_DTO.java @@ -1,5 +1,7 @@ package com.appsmith.server.dtos.ce; +import com.appsmith.external.models.Datasource; +import com.appsmith.external.models.DatasourceStorage; import com.appsmith.server.domains.Context; import com.appsmith.server.dtos.CustomJSLibContextDTO; import com.appsmith.server.dtos.ImportActionCollectionResultDTO; @@ -43,4 +45,9 @@ public class MappedImportableResourcesCE_DTO { // This is being used to carry the resources from ArtifactExchangeJson Map resourceStoreFromArtifactExchangeJson = new HashMap<>(); + + // Dry ops queries + Map> datasourceDryRunQueries = new HashMap<>(); + + Map> datasourceStorageDryRunQueries = new HashMap<>(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/DatasourceContextServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/DatasourceContextServiceCEImpl.java index b2f3a982362d..3693d1348c47 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/DatasourceContextServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/DatasourceContextServiceCEImpl.java @@ -195,7 +195,7 @@ public Mono updateDatasourceAndSetAuthentication(Object connection, Data .setAuthentication(updatableConnection.getAuthenticationDTO( datasourceStorage.getDatasourceConfiguration().getAuthentication())); datasourceStorageMono = datasourceStorageService.updateDatasourceStorage( - datasourceStorage, datasourceStorage.getEnvironmentId(), Boolean.FALSE); + datasourceStorage, datasourceStorage.getEnvironmentId(), Boolean.FALSE, false); } return datasourceStorageMono.thenReturn(connection); } From c41ef62db4cd0e67c8f0f826a84a1f4c04491297 Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Thu, 27 Jun 2024 14:31:00 +0530 Subject: [PATCH 02/11] add dryOps repository class to execute the queries --- .../src/pages/Editor/widgetSidebar/hooks.ts | 6 +-- .../imports/internal/ImportServiceCEImpl.java | 20 +++++++++ .../imports/internal/ImportServiceImpl.java | 7 ++- .../repositories/DryOperationRepository.java | 43 +++++++++++++++++++ 4 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java diff --git a/app/client/src/pages/Editor/widgetSidebar/hooks.ts b/app/client/src/pages/Editor/widgetSidebar/hooks.ts index e50627acf191..ad1a223d8f87 100644 --- a/app/client/src/pages/Editor/widgetSidebar/hooks.ts +++ b/app/client/src/pages/Editor/widgetSidebar/hooks.ts @@ -1,4 +1,3 @@ -import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import { getAllTemplates } from "actions/templateActions"; import type { WidgetTags } from "constants/WidgetConstants"; import { useEffect, useMemo, useState } from "react"; @@ -8,7 +7,6 @@ import { getBuildingBlockExplorerCards, templatesCountSelector, } from "selectors/templatesSelectors"; -import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { groupWidgetCardsByTags } from "../utils"; import { isFixedLayoutSelector } from "selectors/layoutSystemSelectors"; @@ -17,9 +15,7 @@ import { isFixedLayoutSelector } from "selectors/layoutSystemSelectors"; * @returns Object containing cards, grouped cards and entity loading states. */ export const useUIExplorerItems = () => { - const releaseDragDropBuildingBlocks = useFeatureFlag( - FEATURE_FLAG.release_drag_drop_building_blocks_enabled, - ); + const releaseDragDropBuildingBlocks = true; const isFixedLayout = useSelector(isFixedLayoutSelector); const dispatch = useDispatch(); // check if entities have loaded diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java index 6c62de863c2c..3ea798cf6a46 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java @@ -24,6 +24,7 @@ import com.appsmith.server.imports.importable.ImportableService; import com.appsmith.server.imports.internal.artifactbased.ArtifactBasedImportService; import com.appsmith.server.migrations.JsonSchemaMigration; +import com.appsmith.server.repositories.DryOperationRepository; import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; @@ -66,6 +67,7 @@ public class ImportServiceCEImpl implements ImportServiceCE { private final GsonBuilder gsonBuilder; private final ArtifactExchangeJsonAdapter artifactExchangeJsonAdapter; private final JsonSchemaMigration jsonSchemaMigration; + private final DryOperationRepository dryOperationRepository; /** * This method provides the importService specific to the artifact based on the ArtifactType. @@ -502,6 +504,24 @@ private Mono importArtifactInWorkspace( return Mono.error( new AppsmithException(AppsmithError.GENERIC_JSON_IMPORT_ERROR, workspaceId, errorMessage)); }) + // execute dryOps for datasourceStorage + .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO + .getDatasourceStorageDryRunQueries() + .keySet()) + .flatMap(key -> dryOperationRepository.saveDatasourceStorageToDb(mappedImportableResourcesDTO + .getDatasourceStorageDryRunQueries() + .get(key))) + .collectList() + .thenReturn(importableArtifact)) + // execute dry run for datasource + .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO + .getDatasourceDryRunQueries() + .keySet()) + .flatMap(key -> dryOperationRepository.saveDatasourceToDb(mappedImportableResourcesDTO + .getDatasourceDryRunQueries() + .get(key))) + .collectList() + .thenReturn(importableArtifact)) .as(transactionalOperator::transactional); final Mono resultMono = importMono diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceImpl.java index b325a019733f..f2cc3c6ef9fa 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceImpl.java @@ -9,6 +9,7 @@ import com.appsmith.server.imports.importable.ImportableService; import com.appsmith.server.imports.internal.artifactbased.ArtifactBasedImportService; import com.appsmith.server.migrations.JsonSchemaMigration; +import com.appsmith.server.repositories.DryOperationRepository; import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; @@ -30,7 +31,8 @@ public ImportServiceImpl( ImportableService datasourceImportableService, GsonBuilder gsonBuilder, ArtifactExchangeJsonAdapter artifactExchangeJsonAdapter, - JsonSchemaMigration jsonSchemaMigration) { + JsonSchemaMigration jsonSchemaMigration, + DryOperationRepository dryOperationRepository) { super( applicationImportService, sessionUserService, @@ -42,6 +44,7 @@ public ImportServiceImpl( datasourceImportableService, gsonBuilder, artifactExchangeJsonAdapter, - jsonSchemaMigration); + jsonSchemaMigration, + dryOperationRepository); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java new file mode 100644 index 000000000000..570dba2131b1 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java @@ -0,0 +1,43 @@ +package com.appsmith.server.repositories; + +import com.appsmith.external.models.Datasource; +import com.appsmith.external.models.DatasourceStorage; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Flux; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +@RequiredArgsConstructor +public class DryOperationRepository { + + private final DatasourceRepository datasourceRepository; + + private final DatasourceStorageRepository datasourceStorageRepository; + + private Map, AppsmithRepository> repoByEntityClass; + + @PostConstruct + public void init() { + final Map, AppsmithRepository> map = new HashMap<>(); + map.put(Datasource.class, datasourceRepository); + repoByEntityClass = Collections.unmodifiableMap(map); + } + + public AppsmithRepository getRepositoryForEntity(Class entityClass) { + return (AppsmithRepository) repoByEntityClass.get(entityClass); + } + + public Flux saveDatasourceToDb(List datasources) { + return datasourceRepository.saveAll(datasources); + } + + public Flux saveDatasourceStorageToDb(List datasourceStorage) { + return datasourceStorageRepository.saveAll(datasourceStorage); + } +} From 1f13f37a23ba4843f7a814a6a485cade7c1ef5de Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Thu, 27 Jun 2024 14:39:43 +0530 Subject: [PATCH 03/11] fix null check --- .../src/pages/Editor/widgetSidebar/hooks.ts | 6 +++++- .../base/DatasourceServiceCEImpl.java | 17 ++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/client/src/pages/Editor/widgetSidebar/hooks.ts b/app/client/src/pages/Editor/widgetSidebar/hooks.ts index ad1a223d8f87..e50627acf191 100644 --- a/app/client/src/pages/Editor/widgetSidebar/hooks.ts +++ b/app/client/src/pages/Editor/widgetSidebar/hooks.ts @@ -1,3 +1,4 @@ +import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import { getAllTemplates } from "actions/templateActions"; import type { WidgetTags } from "constants/WidgetConstants"; import { useEffect, useMemo, useState } from "react"; @@ -7,6 +8,7 @@ import { getBuildingBlockExplorerCards, templatesCountSelector, } from "selectors/templatesSelectors"; +import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { groupWidgetCardsByTags } from "../utils"; import { isFixedLayoutSelector } from "selectors/layoutSystemSelectors"; @@ -15,7 +17,9 @@ import { isFixedLayoutSelector } from "selectors/layoutSystemSelectors"; * @returns Object containing cards, grouped cards and entity loading states. */ export const useUIExplorerItems = () => { - const releaseDragDropBuildingBlocks = true; + const releaseDragDropBuildingBlocks = useFeatureFlag( + FEATURE_FLAG.release_drag_drop_building_blocks_enabled, + ); const isFixedLayout = useSelector(isFixedLayoutSelector); const dispatch = useDispatch(); // check if entities have loaded diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java index f4e0635cee92..2989560015b2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java @@ -223,14 +223,17 @@ private Mono createEx( } return datasourceStorageService - .create(datasourceStorage, true) + .create(datasourceStorage, isDryOps) .map(datasourceStorage1 -> { - if (datasourceStorageDryRunQueries.containsKey(FieldName.CREATE)) { - datasourceStorageDryRunQueries - .get(FieldName.CREATE) - .add(datasourceStorage1); - } else { - datasourceStorageDryRunQueries.put(FieldName.CREATE, List.of(datasourceStorage1)); + if (datasourceStorageDryRunQueries != null) { + if (datasourceStorageDryRunQueries.containsKey(FieldName.CREATE)) { + datasourceStorageDryRunQueries + .get(FieldName.CREATE) + .add(datasourceStorage1); + } else { + datasourceStorageDryRunQueries.put( + FieldName.CREATE, List.of(datasourceStorage1)); + } } return datasourceStorage1; }); From 4ab0ed3b583969f6579d940c71bcca795206b950 Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Thu, 27 Jun 2024 20:52:18 +0530 Subject: [PATCH 04/11] fix map issue --- .../server/datasources/base/DatasourceServiceCEImpl.java | 9 ++++++--- .../importable/DatasourceImportableServiceCEImpl.java | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java index 2989560015b2..7d30f832da21 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java @@ -227,9 +227,12 @@ private Mono createEx( .map(datasourceStorage1 -> { if (datasourceStorageDryRunQueries != null) { if (datasourceStorageDryRunQueries.containsKey(FieldName.CREATE)) { - datasourceStorageDryRunQueries - .get(FieldName.CREATE) - .add(datasourceStorage1); + List datasourceStorageList = new ArrayList<>(); + datasourceStorageList.addAll( + datasourceStorageDryRunQueries.get(FieldName.CREATE)); + datasourceStorageList.add(datasourceStorage1); + datasourceStorageDryRunQueries.putIfAbsent( + FieldName.CREATE, datasourceStorageList); } else { datasourceStorageDryRunQueries.put( FieldName.CREATE, List.of(datasourceStorage1)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java index 241126423145..e7fbf9ecaaaf 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java @@ -409,6 +409,10 @@ public Flux getEntitiesPresentInWorkspace(String workspaceId) { private void addDryOpsForEntity( String queryType, Map> dryRunOpsMap, Datasource createdDatasource) { if (dryRunOpsMap.containsKey(queryType)) { + List datasourceList = new ArrayList<>(); + datasourceList.addAll(dryRunOpsMap.get(queryType)); + datasourceList.add(createdDatasource); + dryRunOpsMap.put(FieldName.CREATE, datasourceList); dryRunOpsMap.get(queryType).add(createdDatasource); } else { dryRunOpsMap.put(queryType, List.of(createdDatasource)); From a61b08c323baa52418e23d4e2eaa500247798141 Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Sun, 30 Jun 2024 14:47:24 +0530 Subject: [PATCH 05/11] fix issue with map and partial import query execution --- .../base/DatasourceServiceCEImpl.java | 5 ++--- .../DatasourceImportableServiceCEImpl.java | 1 - .../imports/internal/ImportServiceCEImpl.java | 16 +++++++------- .../partial/PartialImportServiceCEImpl.java | 20 ++++++++++++++++++ .../partial/PartialImportServiceImpl.java | 7 +++++-- .../NewActionImportableServiceCEImpl.java | 21 +++++++++++++++++++ .../repositories/DryOperationRepository.java | 1 + .../services/DatasourceServiceTest.java | 2 +- 8 files changed, 58 insertions(+), 15 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java index 7d30f832da21..43ddee791690 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java @@ -225,14 +225,13 @@ private Mono createEx( return datasourceStorageService .create(datasourceStorage, isDryOps) .map(datasourceStorage1 -> { - if (datasourceStorageDryRunQueries != null) { + if (datasourceStorageDryRunQueries != null && isDryOps) { if (datasourceStorageDryRunQueries.containsKey(FieldName.CREATE)) { List datasourceStorageList = new ArrayList<>(); datasourceStorageList.addAll( datasourceStorageDryRunQueries.get(FieldName.CREATE)); datasourceStorageList.add(datasourceStorage1); - datasourceStorageDryRunQueries.putIfAbsent( - FieldName.CREATE, datasourceStorageList); + datasourceStorageDryRunQueries.put(FieldName.CREATE, datasourceStorageList); } else { datasourceStorageDryRunQueries.put( FieldName.CREATE, List.of(datasourceStorage1)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java index e7fbf9ecaaaf..9e50ad102d54 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java @@ -413,7 +413,6 @@ private void addDryOpsForEntity( datasourceList.addAll(dryRunOpsMap.get(queryType)); datasourceList.add(createdDatasource); dryRunOpsMap.put(FieldName.CREATE, datasourceList); - dryRunOpsMap.get(queryType).add(createdDatasource); } else { dryRunOpsMap.put(queryType, List.of(createdDatasource)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java index 3ea798cf6a46..c23235893321 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java @@ -504,21 +504,21 @@ private Mono importArtifactInWorkspace( return Mono.error( new AppsmithException(AppsmithError.GENERIC_JSON_IMPORT_ERROR, workspaceId, errorMessage)); }) - // execute dryOps for datasourceStorage + // execute dry run for datasource .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO - .getDatasourceStorageDryRunQueries() + .getDatasourceDryRunQueries() .keySet()) - .flatMap(key -> dryOperationRepository.saveDatasourceStorageToDb(mappedImportableResourcesDTO - .getDatasourceStorageDryRunQueries() + .flatMap(key -> dryOperationRepository.saveDatasourceToDb(mappedImportableResourcesDTO + .getDatasourceDryRunQueries() .get(key))) .collectList() .thenReturn(importableArtifact)) - // execute dry run for datasource + // execute dryOps for datasourceStorage .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO - .getDatasourceDryRunQueries() + .getDatasourceStorageDryRunQueries() .keySet()) - .flatMap(key -> dryOperationRepository.saveDatasourceToDb(mappedImportableResourcesDTO - .getDatasourceDryRunQueries() + .flatMap(key -> dryOperationRepository.saveDatasourceStorageToDb(mappedImportableResourcesDTO + .getDatasourceStorageDryRunQueries() .get(key))) .collectList() .thenReturn(importableArtifact)) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java index df841c64d410..86fea1a4ff42 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java @@ -33,6 +33,7 @@ import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.refactors.applications.RefactoringService; +import com.appsmith.server.repositories.DryOperationRepository; import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.ApplicationPageService; @@ -93,6 +94,7 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { private final ActionCollectionService actionCollectionService; private final DatasourceService datasourceService; private final CustomJSLibService customJSLibService; + private final DryOperationRepository dryOperationRepository; @Override public Mono importResourceInPage( @@ -241,6 +243,24 @@ private Mono importResourceInPage( .thenReturn(application); }); }) + // execute dry run for datasource + .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO + .getDatasourceDryRunQueries() + .keySet()) + .flatMap(key -> dryOperationRepository.saveDatasourceToDb(mappedImportableResourcesDTO + .getDatasourceDryRunQueries() + .get(key))) + .collectList() + .thenReturn(importableArtifact)) + // execute dryOps for datasourceStorage + .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO + .getDatasourceStorageDryRunQueries() + .keySet()) + .flatMap(key -> dryOperationRepository.saveDatasourceStorageToDb(mappedImportableResourcesDTO + .getDatasourceStorageDryRunQueries() + .get(key))) + .collectList() + .thenReturn(importableArtifact)) .flatMap(application -> { Map fieldNameValueMap = Map.of( FieldName.UNPUBLISHED_JS_LIBS_IDENTIFIER_IN_APPLICATION_CLASS, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceImpl.java index 1e9638bef46a..fca8a44c2c5f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceImpl.java @@ -15,6 +15,7 @@ import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.refactors.applications.RefactoringService; +import com.appsmith.server.repositories.DryOperationRepository; import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.ApplicationPageService; @@ -64,7 +65,8 @@ public PartialImportServiceImpl( NewActionService newActionService, ActionCollectionService actionCollectionService, DatasourceService datasourceService, - CustomJSLibService customJSLibService) { + CustomJSLibService customJSLibService, + DryOperationRepository dryOperationRepository) { super( importService, workspaceService, @@ -92,6 +94,7 @@ public PartialImportServiceImpl( newActionService, actionCollectionService, datasourceService, - customJSLibService); + customJSLibService, + dryOperationRepository); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java index aba07e6176f2..71feec27f11c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java @@ -1,6 +1,7 @@ package com.appsmith.server.newactions.importable; import com.appsmith.external.models.ActionDTO; +import com.appsmith.external.models.Datasource; import com.appsmith.external.models.Policy; import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.constants.FieldName; @@ -317,6 +318,26 @@ private Mono createImportNewActionsMono( branchedNewAction, newAction); + // Check if the action has datasource present + Datasource datasource = + newAction.getUnpublishedAction().getDatasource(); + if (datasource == null || datasource.getPluginId() == null) { + // Since the datasource are not ye saved to db, if we don't update the action with + // correct datasource then + // the action ave will fail due to validation + final String datasourceId = newAction + .getUnpublishedAction() + .getDatasource() + .getId(); + datasource = mappedImportableResourcesDTO.getDatasourceDryRunQueries().values().stream() + .flatMap(List::stream) + .filter(ds -> ds.getId().equals(datasourceId)) + .findFirst() + .orElse(datasource); + datasource.setIsAutoGenerated(false); + newAction.getUnpublishedAction().setDatasource(datasource); + } + // Check if the action has gitSyncId and if it's already in DB if (existingArtifactContainsAction(actionsInCurrentArtifact, newAction)) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java index 570dba2131b1..4bfb4c5b4863 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java @@ -26,6 +26,7 @@ public class DryOperationRepository { public void init() { final Map, AppsmithRepository> map = new HashMap<>(); map.put(Datasource.class, datasourceRepository); + map.put(DatasourceStorage.class, datasourceStorageRepository); repoByEntityClass = Collections.unmodifiableMap(map); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/DatasourceServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/DatasourceServiceTest.java index c23d8aa2fbf3..d7a90a4346d1 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/DatasourceServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/DatasourceServiceTest.java @@ -1994,7 +1994,7 @@ public void verifyTestDatasourceWithSavedDatasourceButNoDatasourceStorageSucceed datasourceStorageService.createDatasourceStorageFromDatasourceStorageDTO(datasourceStorageDTO); Mockito.doReturn(Mono.just(datasourceStorage)) .when(datasourceStorageService) - .create(Mockito.any()); + .create(Mockito.any(), Mockito.anyBoolean()); Datasource dbDatasource = datasourceService.create(datasource).block(); assertThat(dbDatasource.getId()).isNotNull(); From d3f21eb87c3a886dc02fdcd468dcc790af53546f Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Sun, 30 Jun 2024 14:58:49 +0530 Subject: [PATCH 06/11] fix spotless failures --- .../server/datasources/base/DatasourceServiceCEImpl.java | 6 +++--- .../internal/partial/PartialImportServiceCEImpl.java | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java index 8d921c389bc1..96096fca82cd 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java @@ -893,9 +893,9 @@ public Mono archiveById(String id) { @Override public Flux saveAll(List datasourceList) { datasourceList.stream() - .filter(datasource -> datasource.getGitSyncId() == null) - .forEach(datasource -> datasource.setGitSyncId( - datasource.getWorkspaceId() + "_" + Instant.now().toString())); + .filter(datasource -> datasource.getGitSyncId() == null) + .forEach(datasource -> datasource.setGitSyncId( + datasource.getWorkspaceId() + "_" + Instant.now().toString())); return repository.saveAll(datasourceList); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java index 45ef671ab898..7a8543b1d401 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java @@ -63,7 +63,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; From c5daa0980a712cce5d1d335dd36dfa556ff3fe9c Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Mon, 1 Jul 2024 20:35:16 +0530 Subject: [PATCH 07/11] review comments --- .../datasources/base/DatasourceServiceCE.java | 4 +-- .../base/DatasourceServiceCEImpl.java | 34 +++++++++---------- .../DatasourceImportableServiceCEImpl.java | 16 ++++----- .../base/DatasourceStorageServiceCE.java | 3 ++ .../base/DatasourceStorageServiceCEImpl.java | 6 ++++ .../com/appsmith/server/dtos/DBOpsType.java | 9 +++++ .../base/NewActionServiceCEImpl.java | 2 +- .../exports/internal/ExportServiceTests.java | 2 +- .../imports/internal/ImportServiceTests.java | 2 +- .../services/DatasourceServiceTest.java | 2 +- 10 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/DBOpsType.java diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCE.java index c3ccb9508b77..b2f2953e4dce 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCE.java @@ -38,8 +38,6 @@ public interface DatasourceServiceCE { Mono> extractKeysFromDatasource(Datasource datasource); - Mono save(Datasource datasource); - Mono save(Datasource datasource, boolean isDryOps); /** @@ -66,6 +64,8 @@ public interface DatasourceServiceCE { Mono create(Datasource datasource); + Mono createWithoutPermissions(Datasource datasource); + Mono createWithoutPermissions( Datasource datasource, Map> datasourceStorageDryRunQueries); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java index 96096fca82cd..1980f672d322 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java @@ -19,6 +19,7 @@ import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.User; import com.appsmith.server.domains.Workspace; +import com.appsmith.server.dtos.DBOpsType; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.PluginExecutorHelper; @@ -150,6 +151,11 @@ public Mono createWithoutPermissions( return createEx(datasource, null, true, datasourceStorageDryRunQueries); } + @Override + public Mono createWithoutPermissions(Datasource datasource) { + return createEx(datasource, null, false, null); + } + private Mono createEx( @NotNull Datasource datasource, AclPermission permission, @@ -226,15 +232,15 @@ private Mono createEx( .create(datasourceStorage, isDryOps) .map(datasourceStorage1 -> { if (datasourceStorageDryRunQueries != null && isDryOps) { - if (datasourceStorageDryRunQueries.containsKey(FieldName.CREATE)) { + if (datasourceStorageDryRunQueries.containsKey(DBOpsType.SAVE.name())) { + datasourceStorageDryRunQueries + .get(DBOpsType.SAVE.name()) + .add(datasourceStorage1); + } else { List datasourceStorageList = new ArrayList<>(); - datasourceStorageList.addAll( - datasourceStorageDryRunQueries.get(FieldName.CREATE)); datasourceStorageList.add(datasourceStorage1); - datasourceStorageDryRunQueries.put(FieldName.CREATE, datasourceStorageList); - } else { datasourceStorageDryRunQueries.put( - FieldName.CREATE, List.of(datasourceStorage1)); + DBOpsType.SAVE.name(), datasourceStorageList); } } return datasourceStorage1; @@ -385,23 +391,17 @@ public Mono updateDatasourceStorage( }); } - @Override - public Mono save(Datasource datasource) { - if (datasource.getGitSyncId() == null) { - datasource.setGitSyncId( - datasource.getWorkspaceId() + "_" + Instant.now().toString()); - } - return repository.save(datasource); - } - @Override public Mono save(Datasource datasource, boolean isDryOps) { if (datasource.getGitSyncId() == null) { datasource.setGitSyncId( datasource.getWorkspaceId() + "_" + Instant.now().toString()); } - datasource.updateForBulkWriteOperation(); - return Mono.just(datasource); + if (isDryOps) { + datasource.updateForBulkWriteOperation(); + return Mono.just(datasource); + } + return repository.save(datasource); } private Mono validateAndSaveDatasourceToRepository(Datasource datasource, boolean isDryOps) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java index 9e50ad102d54..35f47f80aee0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java @@ -15,6 +15,7 @@ import com.appsmith.server.domains.Artifact; import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.ArtifactExchangeJson; +import com.appsmith.server.dtos.DBOpsType; import com.appsmith.server.dtos.ImportingMetaDTO; import com.appsmith.server.dtos.MappedImportableResourcesDTO; import com.appsmith.server.exceptions.AppsmithError; @@ -215,7 +216,7 @@ private Mono> importDatasources( .map(createdDatasource -> { // Add dry run queries for the datasource addDryOpsForEntity( - FieldName.CREATE, + DBOpsType.SAVE, mappedImportableResourcesDTO.getDatasourceDryRunQueries(), createdDatasource); return Tuples.of( @@ -247,7 +248,7 @@ private Mono> importDatasources( .map(createdDatasource -> { // Add dry run queries for the datasource addDryOpsForEntity( - FieldName.CREATE, + DBOpsType.SAVE, mappedImportableResourcesDTO.getDatasourceDryRunQueries(), createdDatasource); return Tuples.of(importedDatasourceName, createdDatasource.getId()); @@ -407,14 +408,13 @@ public Flux getEntitiesPresentInWorkspace(String workspaceId) { } private void addDryOpsForEntity( - String queryType, Map> dryRunOpsMap, Datasource createdDatasource) { - if (dryRunOpsMap.containsKey(queryType)) { + DBOpsType queryType, Map> dryRunOpsMap, Datasource createdDatasource) { + if (dryRunOpsMap.containsKey(queryType.name())) { + dryRunOpsMap.get(queryType.name()).add(createdDatasource); + } else { List datasourceList = new ArrayList<>(); - datasourceList.addAll(dryRunOpsMap.get(queryType)); datasourceList.add(createdDatasource); - dryRunOpsMap.put(FieldName.CREATE, datasourceList); - } else { - dryRunOpsMap.put(queryType, List.of(createdDatasource)); + dryRunOpsMap.put(queryType.name(), datasourceList); } } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCE.java index 4b018ba2a35a..67252e8e67a5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCE.java @@ -31,6 +31,9 @@ public interface DatasourceStorageServiceCE { Mono findStrictlyByDatasourceIdAndEnvironmentId(String datasourceId, String environmentId); + Mono updateDatasourceStorage( + DatasourceStorage datasourceStorage, String activeEnvironmentId, Boolean IsUserRefreshedUpdate); + Mono updateDatasourceStorage( DatasourceStorage datasourceStorage, String activeEnvironmentId, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCEImpl.java index 52a3820a088e..556880330cc5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasourcestorages/base/DatasourceStorageServiceCEImpl.java @@ -133,6 +133,12 @@ public Mono findStrictlyByDatasourceIdAndEnvironmentId( return repository.findByDatasourceIdAndEnvironmentId(datasourceId, environmentId); } + @Override + public Mono updateDatasourceStorage( + DatasourceStorage datasourceStorage, String activeEnvironmentId, Boolean isUserRefreshedUpdate) { + return updateDatasourceStorage(datasourceStorage, activeEnvironmentId, isUserRefreshedUpdate, false); + } + @Override public Mono updateDatasourceStorage( DatasourceStorage datasourceStorage, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/DBOpsType.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/DBOpsType.java new file mode 100644 index 000000000000..5278a695e227 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/DBOpsType.java @@ -0,0 +1,9 @@ +package com.appsmith.server.dtos; + +public enum DBOpsType { + SAVE, + + UPDATE, + + DELETE +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java index e529e95957b5..bd276c9110c6 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java @@ -1529,7 +1529,7 @@ private Mono updateDatasourcePolicyForPublicAction(NewAction action, Datasource updatedDatasource = policySolution.addPoliciesToExistingObject(datasourcePolicyMap, datasource); - return datasourceService.save(updatedDatasource); + return datasourceService.save(updatedDatasource, false); }); }); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/exports/internal/ExportServiceTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/exports/internal/ExportServiceTests.java index cab998ec48d6..af8244bf6f9e 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/exports/internal/ExportServiceTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/exports/internal/ExportServiceTests.java @@ -2073,7 +2073,7 @@ public void exportApplicationByWhen_WhenGitConnectedAndDatasourceRenamed_Queries Application application = objects.getT2(); datasource.setName("DS_FOR_RENAME_TEST_RENAMED"); return datasourceService - .save(datasource) + .save(datasource, false) .then(exportService.exportByArtifactId( application.getId(), SerialiseArtifactObjective.VERSION_CONTROL, diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/imports/internal/ImportServiceTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/imports/internal/ImportServiceTests.java index 0f03290799b7..c881b2a88482 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/imports/internal/ImportServiceTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/imports/internal/ImportServiceTests.java @@ -5180,7 +5180,7 @@ public void exportApplicationByWhen_WhenGitConnectedAndDatasourceRenamed_Queries Application application = objects.getT2(); datasource.setName("DS_FOR_RENAME_TEST_RENAMED"); return datasourceService - .save(datasource) + .save(datasource, false) .then(exportService.exportByArtifactId(application.getId(), VERSION_CONTROL, APPLICATION)) .map(artifactExchangeJson -> (ApplicationJson) artifactExchangeJson); }); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/DatasourceServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/DatasourceServiceTest.java index d7a90a4346d1..32d45f46864b 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/DatasourceServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/DatasourceServiceTest.java @@ -1284,7 +1284,7 @@ public void checkEncryptionOfAuthenticationDTOAfterRemoval() { datasourceConfiguration2.setUrl("http://test.com"); datasource1.setDatasourceConfiguration(datasourceConfiguration2); datasource1.setName("New Name for update to test that encryption is now gone"); - return datasourceService.save(datasource1); + return datasourceService.save(datasource1, false); }); StepVerifier.create(datasourceMono) From 3a0653f87d26ff34d627817dac79bfede4c18018 Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Mon, 1 Jul 2024 21:04:05 +0530 Subject: [PATCH 08/11] refactor dryOps repo class to execute all the entities in one go --- .../imports/internal/ImportServiceCEImpl.java | 18 ++----------- .../repositories/DryOperationRepository.java | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java index c23235893321..ca662a3b2d83 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java @@ -505,22 +505,8 @@ private Mono importArtifactInWorkspace( new AppsmithException(AppsmithError.GENERIC_JSON_IMPORT_ERROR, workspaceId, errorMessage)); }) // execute dry run for datasource - .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO - .getDatasourceDryRunQueries() - .keySet()) - .flatMap(key -> dryOperationRepository.saveDatasourceToDb(mappedImportableResourcesDTO - .getDatasourceDryRunQueries() - .get(key))) - .collectList() - .thenReturn(importableArtifact)) - // execute dryOps for datasourceStorage - .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO - .getDatasourceStorageDryRunQueries() - .keySet()) - .flatMap(key -> dryOperationRepository.saveDatasourceStorageToDb(mappedImportableResourcesDTO - .getDatasourceStorageDryRunQueries() - .get(key))) - .collectList() + .flatMap(importableArtifact -> dryOperationRepository + .executeAllDbOps(mappedImportableResourcesDTO) .thenReturn(importableArtifact)) .as(transactionalOperator::transactional); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java index 4bfb4c5b4863..d957efc073fc 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/DryOperationRepository.java @@ -2,10 +2,12 @@ import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceStorage; +import com.appsmith.server.dtos.MappedImportableResourcesDTO; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import java.util.Collections; import java.util.HashMap; @@ -41,4 +43,28 @@ public Flux saveDatasourceToDb(List datasources) { public Flux saveDatasourceStorageToDb(List datasourceStorage) { return datasourceStorageRepository.saveAll(datasourceStorage); } + + public Mono executeAllDbOps(MappedImportableResourcesDTO mappedImportableResourcesDTO) { + + Flux> datasourceFLux = Flux.fromIterable(mappedImportableResourcesDTO + .getDatasourceStorageDryRunQueries() + .keySet()) + .flatMap(key -> { + List datasourceList = mappedImportableResourcesDTO + .getDatasourceDryRunQueries() + .get(key); + return saveDatasourceToDb(datasourceList).collectList(); + }); + + Flux> datasourceStorageFLux = Flux.fromIterable(mappedImportableResourcesDTO + .getDatasourceStorageDryRunQueries() + .keySet()) + .flatMap(key -> { + List datasourceStorageList = mappedImportableResourcesDTO + .getDatasourceStorageDryRunQueries() + .get(key); + return saveDatasourceStorageToDb(datasourceStorageList).collectList(); + }); + return Flux.merge(datasourceFLux, datasourceStorageFLux).then(); + } } From 239a42fe414c0ef1161e39b8bec4b07225224c01 Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Mon, 1 Jul 2024 21:04:59 +0530 Subject: [PATCH 09/11] update add to map logic --- .../datasources/base/DatasourceServiceCEImpl.java | 13 +++---------- .../DatasourceImportableServiceCEImpl.java | 8 +------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java index 1980f672d322..c8dc4f898196 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java @@ -232,16 +232,9 @@ private Mono createEx( .create(datasourceStorage, isDryOps) .map(datasourceStorage1 -> { if (datasourceStorageDryRunQueries != null && isDryOps) { - if (datasourceStorageDryRunQueries.containsKey(DBOpsType.SAVE.name())) { - datasourceStorageDryRunQueries - .get(DBOpsType.SAVE.name()) - .add(datasourceStorage1); - } else { - List datasourceStorageList = new ArrayList<>(); - datasourceStorageList.add(datasourceStorage1); - datasourceStorageDryRunQueries.put( - DBOpsType.SAVE.name(), datasourceStorageList); - } + datasourceStorageDryRunQueries + .computeIfAbsent(DBOpsType.SAVE.name(), k -> new ArrayList<>()) + .add(datasourceStorage1); } return datasourceStorage1; }); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java index 35f47f80aee0..69e6d7a7b25e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/importable/DatasourceImportableServiceCEImpl.java @@ -409,12 +409,6 @@ public Flux getEntitiesPresentInWorkspace(String workspaceId) { private void addDryOpsForEntity( DBOpsType queryType, Map> dryRunOpsMap, Datasource createdDatasource) { - if (dryRunOpsMap.containsKey(queryType.name())) { - dryRunOpsMap.get(queryType.name()).add(createdDatasource); - } else { - List datasourceList = new ArrayList<>(); - datasourceList.add(createdDatasource); - dryRunOpsMap.put(queryType.name(), datasourceList); - } + dryRunOpsMap.computeIfAbsent(queryType.name(), k -> new ArrayList<>()).add(createdDatasource); } } From bf4278a876f7946c8b7ad6b118b6831210622745 Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Mon, 1 Jul 2024 21:09:09 +0530 Subject: [PATCH 10/11] null check for datasource id --- .../NewActionImportableServiceCEImpl.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java index 71feec27f11c..25980f2d3715 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java @@ -37,6 +37,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties; @@ -322,13 +323,19 @@ private Mono createImportNewActionsMono( Datasource datasource = newAction.getUnpublishedAction().getDatasource(); if (datasource == null || datasource.getPluginId() == null) { - // Since the datasource are not ye saved to db, if we don't update the action with - // correct datasource then + // Since the datasource are not yet saved to db, if we don't update the action with + // correct datasource, // the action ave will fail due to validation - final String datasourceId = newAction - .getUnpublishedAction() - .getDatasource() - .getId(); + final String datasourceId = Objects.requireNonNull(newAction + .getUnpublishedAction() + .getDatasource()) + .getId() + != null + ? newAction + .getUnpublishedAction() + .getDatasource() + .getId() + : ""; datasource = mappedImportableResourcesDTO.getDatasourceDryRunQueries().values().stream() .flatMap(List::stream) .filter(ds -> ds.getId().equals(datasourceId)) From 1f5ab41dd3ed1434b688aeade89854e1e86c71fd Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Wed, 3 Jul 2024 10:56:29 +0530 Subject: [PATCH 11/11] update dryOps method in partial import --- .../partial/PartialImportServiceCEImpl.java | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java index 7a8543b1d401..71a056833062 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java @@ -249,23 +249,9 @@ private Mono importResourceInPage( .thenReturn(application); }); }) - // execute dry run for datasource - .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO - .getDatasourceDryRunQueries() - .keySet()) - .flatMap(key -> dryOperationRepository.saveDatasourceToDb(mappedImportableResourcesDTO - .getDatasourceDryRunQueries() - .get(key))) - .collectList() - .thenReturn(importableArtifact)) - // execute dryOps for datasourceStorage - .flatMap(importableArtifact -> Flux.fromIterable(mappedImportableResourcesDTO - .getDatasourceStorageDryRunQueries() - .keySet()) - .flatMap(key -> dryOperationRepository.saveDatasourceStorageToDb(mappedImportableResourcesDTO - .getDatasourceStorageDryRunQueries() - .get(key))) - .collectList() + // execute dry run ops + .flatMap(importableArtifact -> dryOperationRepository + .executeAllDbOps(mappedImportableResourcesDTO) .thenReturn(importableArtifact)) .flatMap(application -> { Map fieldNameValueMap = Map.of(