From 1437862f44b3a7c1848c018c532115df4c8d4f06 Mon Sep 17 00:00:00 2001 From: Boubaker Khanfir Date: Fri, 1 Nov 2024 21:04:30 +0100 Subject: [PATCH] feat: Change Kudos Clustering Mechanism with Cache - Meeds-io/meeds#2537 This change will change the Clustering mechanism to use a Cache instead of deprecated and dropped RPCService. --- .../io/meeds/kudos/model/GlobalSettings.java | 15 +--- .../io/meeds/kudos/service/KudosService.java | 89 ++----------------- .../io/meeds/kudos/service/utils/Utils.java | 3 +- .../meeds/kudos/service/KudosServiceTest.java | 2 - .../test/kudos/mock/SpaceServiceMock.java | 11 ++- 5 files changed, 23 insertions(+), 97 deletions(-) diff --git a/kudos-services/src/main/java/io/meeds/kudos/model/GlobalSettings.java b/kudos-services/src/main/java/io/meeds/kudos/model/GlobalSettings.java index e72341f14..2f38258c7 100644 --- a/kudos-services/src/main/java/io/meeds/kudos/model/GlobalSettings.java +++ b/kudos-services/src/main/java/io/meeds/kudos/model/GlobalSettings.java @@ -31,6 +31,7 @@ @NoArgsConstructor @AllArgsConstructor public class GlobalSettings implements Cloneable { + private static final String END_PERIOD_DATE_IN_SECONDS_PARAM = "endPeriodDateInSeconds"; private static final String START_PERIOD_DATE_IN_SECONDS_PARAM = "startPeriodDateInSeconds"; @@ -39,10 +40,6 @@ public class GlobalSettings implements Cloneable { private static final String KUDOS_PER_PERIOD_PARAM = "kudosPerPeriod"; - private static final String ACCESS_PERMISSION_PARAM = "accessPermission"; - - String accessPermission; - long kudosPerPeriod; KudosPeriodType kudosPeriodType = KudosPeriodType.DEFAULT; @@ -50,9 +47,6 @@ public class GlobalSettings implements Cloneable { public JSONObject toJSONObject(boolean includeTransient) { JSONObject jsonObject = new JSONObject(); try { - if (accessPermission != null) { - jsonObject.put(ACCESS_PERMISSION_PARAM, accessPermission); - } jsonObject.put(KUDOS_PER_PERIOD_PARAM, kudosPerPeriod); jsonObject.put(KUDOS_PERIOD_TYPE_PARAM, kudosPeriodType.name()); if (includeTransient) { @@ -96,10 +90,7 @@ public static final GlobalSettings parseStringToObject(String jsonString) { @Override public GlobalSettings clone() { // NOSONAR - try { - return (GlobalSettings) super.clone(); - } catch (CloneNotSupportedException e) { - return new GlobalSettings(accessPermission, kudosPerPeriod, kudosPeriodType); - } + return new GlobalSettings(kudosPerPeriod, kudosPeriodType); } + } diff --git a/kudos-services/src/main/java/io/meeds/kudos/service/KudosService.java b/kudos-services/src/main/java/io/meeds/kudos/service/KudosService.java index 27b3a9438..1cc5f0dfc 100644 --- a/kudos-services/src/main/java/io/meeds/kudos/service/KudosService.java +++ b/kudos-services/src/main/java/io/meeds/kudos/service/KudosService.java @@ -35,26 +35,22 @@ import static io.meeds.kudos.service.utils.Utils.timeFromSeconds; import static io.meeds.kudos.service.utils.Utils.timeToSeconds; -import java.io.Serializable; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.exoplatform.commons.api.settings.SettingService; import org.exoplatform.commons.api.settings.SettingValue; import org.exoplatform.commons.exception.ObjectNotFoundException; import org.exoplatform.services.listener.ListenerService; -import org.exoplatform.services.log.ExoLogger; -import org.exoplatform.services.log.Log; -import org.exoplatform.services.rpc.RPCService; -import org.exoplatform.services.rpc.RemoteCommand; import org.exoplatform.social.core.activity.model.ExoSocialActivity; import org.exoplatform.social.core.identity.model.Identity; import org.exoplatform.social.core.identity.provider.OrganizationIdentityProvider; @@ -72,7 +68,6 @@ import io.meeds.kudos.model.exception.KudosAlreadyLinkedException; import io.meeds.kudos.storage.KudosStorage; -import jakarta.annotation.PostConstruct; import lombok.SneakyThrows; /** @@ -81,12 +76,6 @@ @Service public class KudosService { - private static final Log LOG = ExoLogger.getLogger(KudosService.class); - - private static final String CLUSTER_GLOBAL_SETTINGS_UPDATED = "KudosService-GlobalSettings-Updated"; - - private static final String CLUSTER_NODE_ID = UUID.randomUUID().toString(); - @Autowired private ActivityManager activityManager; @@ -105,42 +94,23 @@ public class KudosService { @Autowired private SettingService settingService; - @Autowired(required = false) - private RPCService rpcService; - - private GlobalSettings globalSettings; - @Value("${kudos.defaultAccessPermission:}") // NOSONAR private String defaultAccessPermission; @Value("${kudos.defaultKudosPerPeriod:3}") private long defaultKudosPerPeriod; - /** - * The generic command used to replicate changes over the cluster - */ - private RemoteCommand reloadSettingsCommand; - - @PostConstruct - public void init() { - GlobalSettings loadedGlobalSettings = loadGlobalSettings(); - if (loadedGlobalSettings == null) { - this.globalSettings = new GlobalSettings(); - this.globalSettings.setKudosPerPeriod(defaultKudosPerPeriod); - } else { - this.globalSettings = loadedGlobalSettings; - } - installClusterListener(); - } - /** * @return {@link GlobalSettings} of Kudos module */ + @Cacheable("Kudos.globalSettings") public GlobalSettings getGlobalSettings() { - if (this.globalSettings == null) { - this.globalSettings = loadGlobalSettings(); + SettingValue globalSettingsValue = settingService.get(KUDOS_CONTEXT, KUDOS_SCOPE, SETTINGS_KEY_NAME); + if (globalSettingsValue == null || StringUtils.isBlank(globalSettingsValue.getValue().toString())) { + return new GlobalSettings(defaultKudosPerPeriod, KudosPeriodType.DEFAULT); + } else { + return GlobalSettings.parseStringToObject(globalSettingsValue.getValue().toString()); } - return this.globalSettings; } /** @@ -148,10 +118,9 @@ public GlobalSettings getGlobalSettings() { * * @param settings {@link GlobalSettings} */ + @CacheEvict(cacheNames = "Kudos.globalSettings", allEntries = true) public void saveGlobalSettings(GlobalSettings settings) { settingService.set(KUDOS_CONTEXT, KUDOS_SCOPE, SETTINGS_KEY_NAME, SettingValue.create(settings.toStringToPersist())); - this.globalSettings = null; - clearCacheClusterWide(); } /** @@ -615,44 +584,4 @@ private long getAllowedKudosPerPeriod() { return storedGlobalSettings == null ? 0 : storedGlobalSettings.getKudosPerPeriod(); } - private GlobalSettings loadGlobalSettings() { - SettingValue globalSettingsValue = settingService.get(KUDOS_CONTEXT, KUDOS_SCOPE, SETTINGS_KEY_NAME); - if (globalSettingsValue == null || StringUtils.isBlank(globalSettingsValue.getValue().toString())) { - return null; - } else { - return GlobalSettings.parseStringToObject(globalSettingsValue.getValue().toString()); - } - } - - private void installClusterListener() { - if (rpcService != null) { - // Clear global settings in current node - // to force reload it from store - // if another cluster node had changed - // the settings - this.reloadSettingsCommand = rpcService.registerCommand(new RemoteCommand() { - public String getId() { - return CLUSTER_GLOBAL_SETTINGS_UPDATED; - } - - public Serializable execute(Serializable[] args) throws Throwable { - if (!CLUSTER_NODE_ID.equals(args[0])) { - KudosService.this.globalSettings = null; - } - return true; - } - }); - } - } - - private void clearCacheClusterWide() { - if (this.reloadSettingsCommand != null) { - try { - rpcService.executeCommandOnAllNodes(this.reloadSettingsCommand, false, CLUSTER_NODE_ID); - } catch (Exception e) { - LOG.warn("An error occurred while clearing global settings cache on other nodes", e); - } - } - } - } diff --git a/kudos-services/src/main/java/io/meeds/kudos/service/utils/Utils.java b/kudos-services/src/main/java/io/meeds/kudos/service/utils/Utils.java index 812ac58de..fd708a502 100644 --- a/kudos-services/src/main/java/io/meeds/kudos/service/utils/Utils.java +++ b/kudos-services/src/main/java/io/meeds/kudos/service/utils/Utils.java @@ -262,8 +262,7 @@ public static KudosPeriod getPeriodOfTime(GlobalSettings globalSettings, LocalDa public static KudosPeriodType getPeriodType(GlobalSettings globalSettings) { KudosPeriodType kudosPeriodType = null; if (globalSettings == null || globalSettings.getKudosPeriodType() == null) { - LOG.warn("Provided globalSettings doesn't have a parametred kudos period type, using MONTH period type: " + globalSettings, - new RuntimeException()); + LOG.warn("Provided globalSettings doesn't have a parametred kudos period type, using MONTH period type: {}", globalSettings); kudosPeriodType = KudosPeriodType.DEFAULT; } else { kudosPeriodType = globalSettings.getKudosPeriodType(); diff --git a/kudos-services/src/test/java/io/meeds/kudos/service/KudosServiceTest.java b/kudos-services/src/test/java/io/meeds/kudos/service/KudosServiceTest.java index eac243a89..cf91b107e 100644 --- a/kudos-services/src/test/java/io/meeds/kudos/service/KudosServiceTest.java +++ b/kudos-services/src/test/java/io/meeds/kudos/service/KudosServiceTest.java @@ -32,7 +32,6 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; @@ -514,7 +513,6 @@ public void testGlobalSettings() { GlobalSettings globalSettings = kudosService.getGlobalSettings(); assertNotNull(globalSettings); assertNotNull(globalSettings.getKudosPeriodType()); - assertTrue(StringUtils.isBlank(globalSettings.getAccessPermission())); assertTrue(globalSettings.getKudosPerPeriod() > 0); } diff --git a/kudos-services/src/test/java/io/meeds/test/kudos/mock/SpaceServiceMock.java b/kudos-services/src/test/java/io/meeds/test/kudos/mock/SpaceServiceMock.java index ab13ed3b8..d40776e48 100644 --- a/kudos-services/src/test/java/io/meeds/test/kudos/mock/SpaceServiceMock.java +++ b/kudos-services/src/test/java/io/meeds/test/kudos/mock/SpaceServiceMock.java @@ -19,6 +19,7 @@ */ package io.meeds.test.kudos.mock; +import java.util.Collections; import java.util.List; import org.apache.commons.lang3.ArrayUtils; @@ -70,7 +71,6 @@ public boolean canRedactOnSpace(Space space, String username) { return space != null && redactor != null && StringUtils.equals(username, redactor); } - @Override public boolean canViewSpace(Space space, String username) { return space != null && member != null && StringUtils.equals(username, member); } @@ -79,4 +79,13 @@ public boolean isSuperManager(String userId) { return false; } + public List findExternalInvitationsSpacesByEmail(String email) { + return Collections.emptyList(); + } + + @Override + public void deleteExternalUserInvitations(String email) { + // + } + }