From 59ec853498805215d976cb95df3b4671e2889399 Mon Sep 17 00:00:00 2001 From: Nidhi Date: Fri, 24 Sep 2021 11:14:14 +0530 Subject: [PATCH] Fixed installation for multiple plugins into organizations (#7767) --- .../encryption/EncryptionHandler.java | 2 +- .../appsmith/server/domains/Organization.java | 3 +- .../server/migrations/DatabaseChangelog.java | 4 +-- .../CustomOrganizationRepository.java | 2 ++ .../CustomOrganizationRepositoryImpl.java | 6 +++- .../services/OrganizationServiceImpl.java | 5 ++-- .../server/services/PluginServiceImpl.java | 9 +++--- .../server/solutions/PluginScheduledTask.java | 29 ++++++++++--------- .../server/configurations/SeedMongoData.java | 5 ++-- 9 files changed, 39 insertions(+), 26 deletions(-) diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/annotations/encryption/EncryptionHandler.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/annotations/encryption/EncryptionHandler.java index aac53e06a6..0b3e254085 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/annotations/encryption/EncryptionHandler.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/annotations/encryption/EncryptionHandler.java @@ -121,7 +121,7 @@ public class EncryptionHandler { field.setAccessible(true); Object fieldValue = ReflectionUtils.getField(field, source); - List list = (List) fieldValue; + Collection list = (Collection) fieldValue; if (list == null || list.isEmpty()) { finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_LIST_UNKNOWN)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Organization.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Organization.java index 7651c4e7d1..e01ba2be85 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Organization.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Organization.java @@ -11,6 +11,7 @@ import org.springframework.data.mongodb.core.mapping.Document; import javax.validation.constraints.NotBlank; import java.util.List; +import java.util.Set; @Getter @@ -29,7 +30,7 @@ public class Organization extends BaseDomain { private String email; - private List plugins; + private Set plugins; private String slug; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog.java index f680f9f633..507c3d7ff8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog.java @@ -184,7 +184,7 @@ public class DatabaseChangelog { private void installPluginToAllOrganizations(MongockTemplate mongockTemplate, String pluginId) { for (Organization organization : mongockTemplate.findAll(Organization.class)) { if (CollectionUtils.isEmpty(organization.getPlugins())) { - organization.setPlugins(new ArrayList<>()); + organization.setPlugins(new HashSet<>()); } final Set installedPlugins = organization.getPlugins() @@ -453,7 +453,7 @@ public class DatabaseChangelog { for (Organization organization : mongoTemplate.findAll(Organization.class)) { if (CollectionUtils.isEmpty(organization.getPlugins())) { - organization.setPlugins(new ArrayList<>()); + organization.setPlugins(new HashSet<>()); } final Set installedPlugins = organization.getPlugins() diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepository.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepository.java index 59d9e1f33a..b2ff23a363 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepository.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepository.java @@ -17,4 +17,6 @@ public interface CustomOrganizationRepository extends AppsmithRepository nextSlugNumber(String slugPrefix); Mono updateUserRoleNames(String userId, String userName); + + Flux findAllOrganizations(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepositoryImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepositoryImpl.java index b96c0ff0b8..3108fabac0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepositoryImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepositoryImpl.java @@ -1,7 +1,6 @@ package com.appsmith.server.repositories; import com.appsmith.server.acl.AclPermission; -import com.appsmith.server.domains.Comment; import com.appsmith.server.domains.Organization; import com.appsmith.server.domains.QOrganization; import lombok.extern.slf4j.Slf4j; @@ -78,4 +77,9 @@ public class CustomOrganizationRepositoryImpl extends BaseAppsmithRepositoryImpl ) .then(); } + + @Override + public Flux findAllOrganizations() { + return mongoOperations.find(new Query(), Organization.class); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java index 7cb93b18db..41653f81f3 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java @@ -38,6 +38,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import static com.appsmith.server.acl.AclPermission.MANAGE_ORGANIZATIONS; import static com.appsmith.server.acl.AclPermission.ORGANIZATION_INVITE_USERS; @@ -171,7 +172,7 @@ public class OrganizationServiceImpl extends BaseService pluginRepository.findByDefaultInstall(true) .map(obj -> new OrganizationPlugin(obj.getId(), OrganizationPluginStatus.FREE)) - .collectList() + .collect(Collectors.toSet()) .map(pluginList -> { org.setPlugins(pluginList); return org; @@ -340,7 +341,7 @@ public class OrganizationServiceImpl extends BaseService getAll() { - return repository.findAll(); + return repository.findAllOrganizations(); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PluginServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PluginServiceImpl.java index b06d986a95..d3daf55685 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PluginServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PluginServiceImpl.java @@ -48,13 +48,14 @@ import java.io.InputStream; import java.net.URL; import java.nio.charset.Charset; import java.nio.file.Path; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; @Slf4j @@ -220,7 +221,7 @@ public class PluginServiceImpl extends BaseService { - List organizationPluginList = organization.getPlugins(); + Set organizationPluginList = organization.getPlugins(); organizationPluginList.removeIf(listPlugin -> listPlugin.getPluginId().equals(pluginDTO.getPluginId())); organization.setPlugins(organizationPluginList); return organizationService.save(organization); @@ -262,9 +263,9 @@ public class PluginServiceImpl extends BaseService { - List organizationPluginList = organization.getPlugins(); + Set organizationPluginList = organization.getPlugins(); if (organizationPluginList == null) { - organizationPluginList = new ArrayList<>(); + organizationPluginList = new HashSet<>(); } OrganizationPlugin organizationPlugin = new OrganizationPlugin(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/PluginScheduledTask.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/PluginScheduledTask.java index 279da4ce17..16d8b47dee 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/PluginScheduledTask.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/PluginScheduledTask.java @@ -40,13 +40,9 @@ public class PluginScheduledTask { private Instant lastUpdatedAt = null; - /** - * Gets the external IP address of this server and pings a data point to indicate that this server instance is live. - * We use an initial delay of two minutes to roughly wait for the application along with the migrations are finished - * and ready. - */ + // Number of milliseconds between the start of each scheduled calls to this method. - @Scheduled(initialDelay = 2 * 60 * 1000 /* two minutes */, fixedRate = 2 * 60 * 60 * 1000 /* two hours */) + @Scheduled(initialDelay = 30 * 1000 /* 30 seconds */, fixedRate = 2 * 60 * 60 * 1000 /* two hours */) public void updateRemotePlugins() { // Get all plugins on this instance final Mono> availablePluginsMono = @@ -60,7 +56,7 @@ public class PluginScheduledTask { final Mono> newPluginsMono = getRemotePlugins(); Mono.zip(availablePluginsMono, newPluginsMono) - .flatMapMany(tuple -> { + .flatMap(tuple -> { final Map availablePlugins = tuple.getT1(); final Map newPlugins = tuple.getT2(); final List updatablePlugins = new ArrayList<>(); @@ -70,17 +66,24 @@ public class PluginScheduledTask { v.setId(availablePlugins.get(k).getId()); updatablePlugins.add(v); } else { + v.setId(null); insertablePlugins.add(v); } }); - final Flux updatedPluginsFlux = pluginService.saveAll(updatablePlugins); - final Flux organizationFlux = pluginService.saveAll(insertablePlugins) - .filter(Plugin::getDefaultInstall) - .collectList() - .flatMapMany(pluginService::installDefaultPlugins); + final Mono> updatedPluginsFlux = pluginService.saveAll(updatablePlugins) + .collectList(); + final Mono> organizationFlux = + Flux.fromIterable(insertablePlugins) + .flatMap(pluginService::create) + .filter(Plugin::getDefaultInstall) + .collectList() + .flatMapMany(pluginService::installDefaultPlugins) + .collectList(); - return updatedPluginsFlux.zipWith(organizationFlux); + return updatedPluginsFlux + .zipWith(organizationFlux) + .then(); }) .subscribeOn(Schedulers.single()) .subscribe(); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/SeedMongoData.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/SeedMongoData.java index a79dacf963..0e724bf292 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/SeedMongoData.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/SeedMongoData.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import static com.appsmith.server.acl.AclPermission.MANAGE_APPLICATIONS; import static com.appsmith.server.acl.AclPermission.MANAGE_ORGANIZATIONS; @@ -177,12 +178,12 @@ public class SeedMongoData { Flux organizationFlux = mongoTemplate .find(new Query().addCriteria(where("name").in(pluginData[0][0], pluginData[1][0], pluginData[2][0])), Plugin.class) .map(plugin -> new OrganizationPlugin(plugin.getId(), OrganizationPluginStatus.FREE)) - .collectList() + .collect(Collectors.toSet()) .cache() .repeat() .zipWithIterable(List.of(orgData)) .map(tuple -> { - final List orgPlugins = tuple.getT1(); + final Set orgPlugins = tuple.getT1(); final Object[] orgArray = tuple.getT2(); Organization organization = new Organization();