From dd73e8b91fec218c0cf164bf472fbc2efa7a7d8e Mon Sep 17 00:00:00 2001 From: Nidhi Date: Tue, 14 May 2024 10:24:21 +0530 Subject: [PATCH] fix: Enable atomic pushes in git using an environment configuration (#33367) Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../src/ce/constants/tenantConstants.ts | 1 + .../ce/pages/AdminSettings/config/general.tsx | 10 +++ .../appsmith/git/service/GitExecutorImpl.java | 7 +- .../git/service/ce/GitExecutorCEImpl.java | 78 ++++++++++--------- .../connectionpool}/ConnectionPoolConfig.java | 2 +- .../ConnectionPoolConfigCE.java | 2 +- .../ConnectionPoolConfigCECompatible.java | 2 +- .../configurations/git/GitConfig.java | 3 + .../configurations/git/GitConfigCE.java | 7 ++ .../git/GitConfigCECompatible.java | 3 + .../external/helpers/AppsmithBeanUtils.java | 15 ++++ .../com/external/plugins/PostgresPlugin.java | 3 +- .../external/plugins/PostgresPluginTest.java | 2 +- .../git/ApplicationGitFileUtilsCEImpl.java | 18 +---- .../ConnectionPoolConfigCECompatibleImpl.java | 4 +- .../ConnectionPoolConfigCEImpl.java | 4 +- .../ConnectionPoolConfigImpl.java | 4 +- .../git/GitConfigCECompatibleImpl.java | 12 +++ .../configurations/git/GitConfigCEImpl.java | 20 +++++ .../configurations/git/GitConfigImpl.java | 12 +++ .../domains/ce/TenantConfigurationCE.java | 3 + ...ushAllowedEnvVarToTenantConfiguration.java | 48 ++++++++++++ .../server/solutions/ce/EnvManagerCEImpl.java | 24 ++++-- .../ConnectionPoolConfigCETest.java | 2 +- 24 files changed, 212 insertions(+), 74 deletions(-) rename app/server/appsmith-interfaces/src/main/java/com/appsmith/external/{connectionpoolconfig/configurations => configurations/connectionpool}/ConnectionPoolConfig.java (55%) rename app/server/appsmith-interfaces/src/main/java/com/appsmith/external/{connectionpoolconfig/configurations => configurations/connectionpool}/ConnectionPoolConfigCE.java (65%) rename app/server/appsmith-interfaces/src/main/java/com/appsmith/external/{connectionpoolconfig/configurations => configurations/connectionpool}/ConnectionPoolConfigCECompatible.java (55%) create mode 100644 app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfig.java create mode 100644 app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfigCE.java create mode 100644 app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfigCECompatible.java rename app/server/appsmith-server/src/main/java/com/appsmith/server/{connectionpoolconfig/configurations => configurations/connectionpool}/ConnectionPoolConfigCECompatibleImpl.java (55%) rename app/server/appsmith-server/src/main/java/com/appsmith/server/{connectionpoolconfig/configurations => configurations/connectionpool}/ConnectionPoolConfigCEImpl.java (67%) rename app/server/appsmith-server/src/main/java/com/appsmith/server/{connectionpoolconfig/configurations => configurations/connectionpool}/ConnectionPoolConfigImpl.java (59%) create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCECompatibleImpl.java create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCEImpl.java create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigImpl.java create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration055AddIsAtomicPushAllowedEnvVarToTenantConfiguration.java diff --git a/app/client/src/ce/constants/tenantConstants.ts b/app/client/src/ce/constants/tenantConstants.ts index 7622d70709..8ab31888f4 100644 --- a/app/client/src/ce/constants/tenantConstants.ts +++ b/app/client/src/ce/constants/tenantConstants.ts @@ -6,6 +6,7 @@ export const tenantConfigConnection: string[] = [ "showRolesAndGroups", "hideWatermark", "userSessionTimeoutInMinutes", + "isAtomicPushAllowed", ]; export const RESTART_POLL_TIMEOUT = 2 * 150 * 1000; diff --git a/app/client/src/ce/pages/AdminSettings/config/general.tsx b/app/client/src/ce/pages/AdminSettings/config/general.tsx index 9cbd024a64..8127b6a53e 100644 --- a/app/client/src/ce/pages/AdminSettings/config/general.tsx +++ b/app/client/src/ce/pages/AdminSettings/config/general.tsx @@ -121,6 +121,15 @@ export const APPSMITH_USER_SESSION_TIMEOUT_SETTING: Setting = { isDisabled: () => true, }; +export const APPSMITH_IS_ATOMIC_PUSH_ALLOWED: Setting = { + id: "isAtomicPushAllowed", + name: "isAtomicPushAllowed", + category: SettingCategories.GENERAL, + controlType: SettingTypes.CHECKBOX, + label: "Allow atomic pushes", + text: "Git operations on this tenant should attempt to perform pushes atomically", +}; + export const APPSMITH_ALLOWED_FRAME_ANCESTORS_SETTING: Setting = { id: "APPSMITH_ALLOWED_FRAME_ANCESTORS", name: "APPSMITH_ALLOWED_FRAME_ANCESTORS", @@ -201,6 +210,7 @@ export const config: AdminConfigType = { APPSMITH_SHOW_ROLES_AND_GROUPS_SETTING, APPSMITH_SINGLE_USER_PER_SESSION_SETTING, APPSMITH_USER_SESSION_TIMEOUT_SETTING, + APPSMITH_IS_ATOMIC_PUSH_ALLOWED, APPSMITH_ALLOWED_FRAME_ANCESTORS_SETTING, ], } as AdminConfigType; diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/GitExecutorImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/GitExecutorImpl.java index 464b790b82..f0ad7bdb12 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/GitExecutorImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/GitExecutorImpl.java @@ -1,5 +1,6 @@ package com.appsmith.git.service; +import com.appsmith.external.configurations.git.GitConfig; import com.appsmith.external.git.GitExecutor; import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.service.ce.GitExecutorCEImpl; @@ -12,8 +13,8 @@ import org.springframework.stereotype.Component; @Primary @Slf4j public class GitExecutorImpl extends GitExecutorCEImpl implements GitExecutor { - - public GitExecutorImpl(GitServiceConfig gitServiceConfig, ObservationRegistry observationRegistry) { - super(gitServiceConfig, observationRegistry); + public GitExecutorImpl( + GitServiceConfig gitServiceConfig, GitConfig gitConfig, ObservationRegistry observationRegistry) { + super(gitServiceConfig, gitConfig, observationRegistry); } } diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java index 0e26a73b40..d5adac72ea 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java @@ -1,5 +1,6 @@ package com.appsmith.git.service.ce; +import com.appsmith.external.configurations.git.GitConfig; import com.appsmith.external.constants.AnalyticsEvents; import com.appsmith.external.constants.ErrorReferenceDocUrl; import com.appsmith.external.dtos.GitBranchDTO; @@ -80,6 +81,7 @@ public class GitExecutorCEImpl implements GitExecutor { private final RepositoryHelper repositoryHelper = new RepositoryHelper(); private final GitServiceConfig gitServiceConfig; + private final GitConfig gitConfig; protected final ObservationRegistry observationRegistry; @@ -222,43 +224,49 @@ public class GitExecutorCEImpl implements GitExecutor { // open the repo Path baseRepoPath = createRepoPath(repoSuffix); - return Mono.using( - () -> Git.open(baseRepoPath.toFile()), - git -> Mono.fromCallable(() -> { - log.debug(Thread.currentThread().getName() + ": pushing changes to remote " - + remoteUrl); - // open the repo - Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( - baseRepoPath, AnalyticsEvents.GIT_PUSH.getEventName()); - TransportConfigCallback transportConfigCallback = - new SshTransportConfigCallback(privateKey, publicKey); + return gitConfig + .getIsAtomicPushAllowed() + .flatMap(isAtomicPushAllowed -> { + return Mono.using( + () -> Git.open(baseRepoPath.toFile()), + git -> Mono.fromCallable(() -> { + log.debug(Thread.currentThread().getName() + ": pushing changes to remote " + + remoteUrl); + // open the repo + Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( + baseRepoPath, AnalyticsEvents.GIT_PUSH.getEventName()); + TransportConfigCallback transportConfigCallback = + new SshTransportConfigCallback(privateKey, publicKey); - StringBuilder result = new StringBuilder("Pushed successfully with status : "); - git.push() - .setTransportConfigCallback(transportConfigCallback) - .setRemote(remoteUrl) - .call() - .forEach(pushResult -> pushResult - .getRemoteUpdates() - .forEach(remoteRefUpdate -> { - result.append(remoteRefUpdate.getStatus()) - .append(","); - if (!StringUtils.isEmptyOrNull(remoteRefUpdate.getMessage())) { - result.append(remoteRefUpdate.getMessage()) + StringBuilder result = new StringBuilder("Pushed successfully with status : "); + git.push() + .setAtomic(isAtomicPushAllowed) + .setTransportConfigCallback(transportConfigCallback) + .setRemote(remoteUrl) + .call() + .forEach(pushResult -> pushResult + .getRemoteUpdates() + .forEach(remoteRefUpdate -> { + result.append(remoteRefUpdate.getStatus()) .append(","); - } - })); - // We can support username and password in future if needed - // pushCommand.setCredentialsProvider(new - // UsernamePasswordCredentialsProvider("username", - // "password")); - processStopwatch.stopAndLogTimeInMillis(); - return result.substring(0, result.length() - 1); - }) - .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) - .name(GitSpan.FS_PUSH) - .tap(Micrometer.observation(observationRegistry)), - Git::close) + if (!StringUtils.isEmptyOrNull( + remoteRefUpdate.getMessage())) { + result.append(remoteRefUpdate.getMessage()) + .append(","); + } + })); + // We can support username and password in future if needed + // pushCommand.setCredentialsProvider(new + // UsernamePasswordCredentialsProvider("username", + // "password")); + processStopwatch.stopAndLogTimeInMillis(); + return result.substring(0, result.length() - 1); + }) + .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) + .name(GitSpan.FS_PUSH) + .tap(Micrometer.observation(observationRegistry)), + Git::close); + }) .subscribeOn(scheduler); } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/connectionpoolconfig/configurations/ConnectionPoolConfig.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/connectionpool/ConnectionPoolConfig.java similarity index 55% rename from app/server/appsmith-interfaces/src/main/java/com/appsmith/external/connectionpoolconfig/configurations/ConnectionPoolConfig.java rename to app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/connectionpool/ConnectionPoolConfig.java index 66e84e22df..80a058f1d1 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/connectionpoolconfig/configurations/ConnectionPoolConfig.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/connectionpool/ConnectionPoolConfig.java @@ -1,3 +1,3 @@ -package com.appsmith.external.connectionpoolconfig.configurations; +package com.appsmith.external.configurations.connectionpool; public interface ConnectionPoolConfig extends ConnectionPoolConfigCECompatible {} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/connectionpoolconfig/configurations/ConnectionPoolConfigCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/connectionpool/ConnectionPoolConfigCE.java similarity index 65% rename from app/server/appsmith-interfaces/src/main/java/com/appsmith/external/connectionpoolconfig/configurations/ConnectionPoolConfigCE.java rename to app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/connectionpool/ConnectionPoolConfigCE.java index f093a42d96..56e8b2c22a 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/connectionpoolconfig/configurations/ConnectionPoolConfigCE.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/connectionpool/ConnectionPoolConfigCE.java @@ -1,4 +1,4 @@ -package com.appsmith.external.connectionpoolconfig.configurations; +package com.appsmith.external.configurations.connectionpool; import reactor.core.publisher.Mono; diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/connectionpoolconfig/configurations/ConnectionPoolConfigCECompatible.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/connectionpool/ConnectionPoolConfigCECompatible.java similarity index 55% rename from app/server/appsmith-interfaces/src/main/java/com/appsmith/external/connectionpoolconfig/configurations/ConnectionPoolConfigCECompatible.java rename to app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/connectionpool/ConnectionPoolConfigCECompatible.java index 12fb7a3b0f..3471828225 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/connectionpoolconfig/configurations/ConnectionPoolConfigCECompatible.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/connectionpool/ConnectionPoolConfigCECompatible.java @@ -1,3 +1,3 @@ -package com.appsmith.external.connectionpoolconfig.configurations; +package com.appsmith.external.configurations.connectionpool; public interface ConnectionPoolConfigCECompatible extends ConnectionPoolConfigCE {} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfig.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfig.java new file mode 100644 index 0000000000..364b1ecde6 --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfig.java @@ -0,0 +1,3 @@ +package com.appsmith.external.configurations.git; + +public interface GitConfig extends GitConfigCECompatible {} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfigCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfigCE.java new file mode 100644 index 0000000000..93b055874d --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfigCE.java @@ -0,0 +1,7 @@ +package com.appsmith.external.configurations.git; + +import reactor.core.publisher.Mono; + +public interface GitConfigCE { + Mono getIsAtomicPushAllowed(); +} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfigCECompatible.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfigCECompatible.java new file mode 100644 index 0000000000..ce29e62a32 --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/configurations/git/GitConfigCECompatible.java @@ -0,0 +1,3 @@ +package com.appsmith.external.configurations.git; + +public interface GitConfigCECompatible extends GitConfigCE {} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/helpers/AppsmithBeanUtils.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/helpers/AppsmithBeanUtils.java index 824d504c97..1c90655bf2 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/helpers/AppsmithBeanUtils.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/helpers/AppsmithBeanUtils.java @@ -6,10 +6,13 @@ import org.springframework.beans.BeanWrapperImpl; import org.springframework.beans.PropertyAccessorFactory; import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Stream; public final class AppsmithBeanUtils { @@ -124,4 +127,16 @@ public final class AppsmithBeanUtils { return values; } + + public static Stream getAllFields(Class currentType) { + + Set> classes = new HashSet<>(); + + while (currentType != null) { + classes.add(currentType); + currentType = currentType.getSuperclass(); + } + + return classes.stream().flatMap(currentClass -> Arrays.stream(currentClass.getDeclaredFields())); + } } diff --git a/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/PostgresPlugin.java b/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/PostgresPlugin.java index 803efdeef7..003b8ddde3 100644 --- a/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/PostgresPlugin.java +++ b/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/PostgresPlugin.java @@ -1,6 +1,6 @@ package com.external.plugins; -import com.appsmith.external.connectionpoolconfig.configurations.ConnectionPoolConfig; +import com.appsmith.external.configurations.connectionpool.ConnectionPoolConfig; import com.appsmith.external.constants.DataType; import com.appsmith.external.datatypes.AppsmithType; import com.appsmith.external.dtos.ExecuteActionDTO; @@ -89,7 +89,6 @@ import static com.appsmith.external.helpers.PluginUtils.getIdenticalColumns; import static com.appsmith.external.helpers.PluginUtils.getPSParamLabel; import static com.appsmith.external.helpers.Sizeof.sizeof; import static com.appsmith.external.helpers.SmartSubstitutionHelper.replaceQuestionMarkWithDollarIndex; -import static com.appsmith.external.models.SSLDetails.AuthType.VERIFY_CA; import static com.external.plugins.utils.PostgresDataTypeUtils.DataType.BOOL; import static com.external.plugins.utils.PostgresDataTypeUtils.DataType.DATE; import static com.external.plugins.utils.PostgresDataTypeUtils.DataType.DECIMAL; diff --git a/app/server/appsmith-plugins/postgresPlugin/src/test/java/com/external/plugins/PostgresPluginTest.java b/app/server/appsmith-plugins/postgresPlugin/src/test/java/com/external/plugins/PostgresPluginTest.java index 778dbe9d5e..7c2b084aeb 100644 --- a/app/server/appsmith-plugins/postgresPlugin/src/test/java/com/external/plugins/PostgresPluginTest.java +++ b/app/server/appsmith-plugins/postgresPlugin/src/test/java/com/external/plugins/PostgresPluginTest.java @@ -1,6 +1,6 @@ package com.external.plugins; -import com.appsmith.external.connectionpoolconfig.configurations.ConnectionPoolConfig; +import com.appsmith.external.configurations.connectionpool.ConnectionPoolConfig; import com.appsmith.external.datatypes.ClientDataType; import com.appsmith.external.dtos.ExecuteActionDTO; import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java index 22d4a795fb..e52b8ea532 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java @@ -1,6 +1,7 @@ package com.appsmith.server.applications.git; import com.appsmith.external.git.FileInterface; +import com.appsmith.external.helpers.AppsmithBeanUtils; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.ApplicationGitReference; import com.appsmith.external.models.ArtifactGitReference; @@ -40,14 +41,12 @@ import reactor.core.publisher.Mono; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Arrays; 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 java.util.stream.Stream; import static com.appsmith.external.git.constants.GitConstants.NAME_SEPARATOR; import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties; @@ -141,7 +140,7 @@ public class ApplicationGitFileUtilsCEImpl implements ArtifactGitFileUtilsCE keys = getAllFields(applicationJson) + Iterable keys = AppsmithBeanUtils.getAllFields(applicationJson.getClass()) .map(Field::getName) .filter(name -> !getBlockedMetadataFields().contains(name)) .collect(Collectors.toList()); @@ -304,19 +303,6 @@ public class ApplicationGitFileUtilsCEImpl implements ArtifactGitFileUtilsCE getAllFields(ApplicationJson applicationJson) { - Class currentType = applicationJson.getClass(); - - Set> classes = new HashSet<>(); - - while (currentType != null) { - classes.add(currentType); - currentType = currentType.getSuperclass(); - } - - return classes.stream().flatMap(currentClass -> Arrays.stream(currentClass.getDeclaredFields())); - } - private void removeUnwantedFieldsFromApplication(Application application) { // Don't commit application name as while importing we are using the repoName as application name application.setName(null); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCECompatibleImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/connectionpool/ConnectionPoolConfigCECompatibleImpl.java similarity index 55% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCECompatibleImpl.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/connectionpool/ConnectionPoolConfigCECompatibleImpl.java index 74ee25d6c6..d859a29b6f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCECompatibleImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/connectionpool/ConnectionPoolConfigCECompatibleImpl.java @@ -1,6 +1,6 @@ -package com.appsmith.server.connectionpoolconfig.configurations; +package com.appsmith.server.configurations.connectionpool; -import com.appsmith.external.connectionpoolconfig.configurations.ConnectionPoolConfigCECompatible; +import com.appsmith.external.configurations.connectionpool.ConnectionPoolConfigCECompatible; import org.springframework.stereotype.Component; @Component diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/connectionpool/ConnectionPoolConfigCEImpl.java similarity index 67% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCEImpl.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/connectionpool/ConnectionPoolConfigCEImpl.java index 16db95e0a8..3d6beebc2f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/connectionpool/ConnectionPoolConfigCEImpl.java @@ -1,6 +1,6 @@ -package com.appsmith.server.connectionpoolconfig.configurations; +package com.appsmith.server.configurations.connectionpool; -import com.appsmith.external.connectionpoolconfig.configurations.ConnectionPoolConfigCE; +import com.appsmith.external.configurations.connectionpool.ConnectionPoolConfigCE; import reactor.core.publisher.Mono; public class ConnectionPoolConfigCEImpl implements ConnectionPoolConfigCE { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/connectionpool/ConnectionPoolConfigImpl.java similarity index 59% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigImpl.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/connectionpool/ConnectionPoolConfigImpl.java index 6d64667672..92892a91fd 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/connectionpool/ConnectionPoolConfigImpl.java @@ -1,6 +1,6 @@ -package com.appsmith.server.connectionpoolconfig.configurations; +package com.appsmith.server.configurations.connectionpool; -import com.appsmith.external.connectionpoolconfig.configurations.ConnectionPoolConfig; +import com.appsmith.external.configurations.connectionpool.ConnectionPoolConfig; import org.springframework.stereotype.Component; @Component diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCECompatibleImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCECompatibleImpl.java new file mode 100644 index 0000000000..90fbc54eb4 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCECompatibleImpl.java @@ -0,0 +1,12 @@ +package com.appsmith.server.configurations.git; + +import com.appsmith.external.configurations.git.GitConfigCECompatible; +import com.appsmith.server.services.TenantService; +import org.springframework.stereotype.Component; + +@Component +public class GitConfigCECompatibleImpl extends GitConfigCEImpl implements GitConfigCECompatible { + public GitConfigCECompatibleImpl(TenantService tenantService) { + super(tenantService); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCEImpl.java new file mode 100644 index 0000000000..dc0950b714 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCEImpl.java @@ -0,0 +1,20 @@ +package com.appsmith.server.configurations.git; + +import com.appsmith.external.configurations.git.GitConfigCE; +import com.appsmith.server.services.TenantService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +@RequiredArgsConstructor +@Component +public class GitConfigCEImpl implements GitConfigCE { + + private final TenantService tenantService; + + @Override + public Mono getIsAtomicPushAllowed() { + return tenantService.getTenantConfiguration().map(tenant -> tenant.getTenantConfiguration() + .getIsAtomicPushAllowed()); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigImpl.java new file mode 100644 index 0000000000..3cef3e9c08 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigImpl.java @@ -0,0 +1,12 @@ +package com.appsmith.server.configurations.git; + +import com.appsmith.external.configurations.git.GitConfig; +import com.appsmith.server.services.TenantService; +import org.springframework.stereotype.Component; + +@Component +public class GitConfigImpl extends GitConfigCECompatibleImpl implements GitConfig { + public GitConfigImpl(TenantService tenantService) { + super(tenantService); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/TenantConfigurationCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/TenantConfigurationCE.java index 4d11d668be..ad8c610c41 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/TenantConfigurationCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/TenantConfigurationCE.java @@ -53,6 +53,8 @@ public class TenantConfigurationCE { Boolean isStrongPasswordPolicyEnabled; + private Boolean isAtomicPushAllowed; + public void addThirdPartyAuth(String auth) { if (thirdPartyAuths == null) { thirdPartyAuths = new ArrayList<>(); @@ -77,6 +79,7 @@ public class TenantConfigurationCE { featuresWithPendingMigration = tenantConfiguration.getFeaturesWithPendingMigration(); migrationStatus = tenantConfiguration.getMigrationStatus(); isStrongPasswordPolicyEnabled = tenantConfiguration.getIsStrongPasswordPolicyEnabled(); + isAtomicPushAllowed = tenantConfiguration.getIsAtomicPushAllowed(); } public Boolean isEmailVerificationEnabled() { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration055AddIsAtomicPushAllowedEnvVarToTenantConfiguration.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration055AddIsAtomicPushAllowedEnvVarToTenantConfiguration.java new file mode 100644 index 0000000000..fb1234a88e --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration055AddIsAtomicPushAllowedEnvVarToTenantConfiguration.java @@ -0,0 +1,48 @@ +package com.appsmith.server.migrations.db.ce; + +import com.appsmith.server.domains.Tenant; +import com.appsmith.server.domains.TenantConfiguration; +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; + +import java.io.IOException; +import java.util.Objects; + +import static org.springframework.data.mongodb.core.query.Criteria.where; + +@Slf4j +@ChangeUnit(order = "055", id = "add-is-atomic-push-allowed-env-variable-tenant-configuration") +public class Migration055AddIsAtomicPushAllowedEnvVarToTenantConfiguration { + private final MongoTemplate mongoTemplate; + + public Migration055AddIsAtomicPushAllowedEnvVarToTenantConfiguration(MongoTemplate mongoTemplate) { + this.mongoTemplate = mongoTemplate; + } + + @RollbackExecution + public void executionRollback() {} + + @Execution + public void executeMigration() throws IOException { + Query tenantQuery = new Query(); + tenantQuery.addCriteria(where(Tenant.Fields.slug).is("default")); + Tenant defaultTenant = mongoTemplate.findOne(tenantQuery, Tenant.class); + + boolean isAtomicPushAllowed = false; + + TenantConfiguration defaultTenantConfiguration = new TenantConfiguration(); + if (defaultTenant == null) { + throw new IllegalStateException("Default tenant not found"); + } + if (Objects.nonNull(defaultTenant.getTenantConfiguration())) { + defaultTenantConfiguration = defaultTenant.getTenantConfiguration(); + } + defaultTenantConfiguration.setIsAtomicPushAllowed(isAtomicPushAllowed); + defaultTenant.setTenantConfiguration(defaultTenantConfiguration); + mongoTemplate.save(defaultTenant); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java index afe128147f..1997283a82 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java @@ -1,6 +1,7 @@ package com.appsmith.server.solutions.ce; import com.appsmith.external.constants.AnalyticsEvents; +import com.appsmith.external.helpers.AppsmithBeanUtils; import com.appsmith.server.configurations.CommonConfig; import com.appsmith.server.configurations.EmailConfig; import com.appsmith.server.configurations.GoogleRecaptchaConfig; @@ -32,6 +33,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.mail.MessagingException; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.beanutils.ConvertUtils; import org.jetbrains.annotations.NotNull; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.buffer.DataBufferUtils; @@ -63,7 +65,6 @@ import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -296,8 +297,7 @@ public class EnvManagerCEImpl implements EnvManagerCE { * @return */ private Set allowedTenantConfiguration() { - Field[] fields = TenantConfiguration.class.getDeclaredFields(); - return Arrays.stream(fields) + return AppsmithBeanUtils.getAllFields(TenantConfiguration.class) .map(field -> { JsonProperty jsonProperty = field.getDeclaredAnnotation(JsonProperty.class); return jsonProperty == null ? field.getName() : jsonProperty.value(); @@ -314,20 +314,30 @@ public class EnvManagerCEImpl implements EnvManagerCE { * @param value */ private void setConfigurationByKey(TenantConfiguration tenantConfiguration, String key, String value) { - Field[] fields = tenantConfiguration.getClass().getDeclaredFields(); - for (Field field : fields) { + Stream fieldStream = AppsmithBeanUtils.getAllFields(TenantConfiguration.class); + fieldStream.forEach(field -> { JsonProperty jsonProperty = field.getDeclaredAnnotation(JsonProperty.class); if (jsonProperty != null && jsonProperty.value().equals(key)) { try { field.setAccessible(true); - field.set(tenantConfiguration, value); + Object typedValue = ConvertUtils.convert(value, field.getType()); + field.set(tenantConfiguration, typedValue); } catch (IllegalAccessException e) { // Catch the error, log it and then do nothing. log.error( "Got error while parsing the JSON annotations from TenantConfiguration class. Cause: ", e); } + } else if (field.getName().equals(key)) { + try { + field.setAccessible(true); + Object typedValue = ConvertUtils.convert(value, field.getType()); + field.set(tenantConfiguration, typedValue); + } catch (IllegalAccessException e) { + // Catch the error, log it and then do nothing. + log.error("Got error while attempting to save property to TenantConfiguration class. Cause: ", e); + } } - } + }); } private Mono updateTenantConfiguration(String tenantId, Map changes) { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCETest.java index f9570cead6..fbd1042483 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/connectionpoolconfig/configurations/ConnectionPoolConfigCETest.java @@ -1,6 +1,6 @@ package com.appsmith.server.connectionpoolconfig.configurations; -import com.appsmith.external.connectionpoolconfig.configurations.ConnectionPoolConfig; +import com.appsmith.external.configurations.connectionpool.ConnectionPoolConfig; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired;