diff --git a/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardReportService.java b/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardReportService.java index d72f570fd..cc7c42bef 100644 --- a/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardReportService.java +++ b/wallet-api/src/main/java/org/exoplatform/wallet/reward/service/RewardReportService.java @@ -75,6 +75,11 @@ public interface RewardReportService { */ void saveRewardReport(RewardReport rewardReport); + /** + * @return true if reward sending status storage is in progress, else return false + */ + boolean isRewardSendingInProgress(); + /** * @return a {@link List} of {@link RewardPeriod} that are in progress */ diff --git a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/dao/RewardDAO.java b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/dao/RewardDAO.java index 7515f6666..8c99aa00f 100644 --- a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/dao/RewardDAO.java +++ b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/dao/RewardDAO.java @@ -22,6 +22,9 @@ import javax.persistence.Query; import javax.persistence.TypedQuery; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + import org.exoplatform.commons.api.persistence.ExoTransactional; import org.exoplatform.commons.persistence.impl.GenericDAOJPAImpl; import org.exoplatform.services.log.ExoLogger; @@ -90,7 +93,19 @@ private double toNotNullDouble(Double result) { } private WalletRewardEntity getFirstItem(List resultList) { - return resultList == null || resultList.isEmpty() ? null : resultList.get(0); + if (CollectionUtils.isEmpty(resultList)) { + return null; + } else { + return resultList.stream().filter(r -> StringUtils.isNotBlank(r.getTransactionHash())).sorted((r1, r2) -> { + if (r1.getTokensSent() > r2.getTokensSent()) { + return 1; + } else if (r2.getTokensSent() > r1.getTokensSent()) { + return -1; + } else { + return 0; + } + }).findFirst().orElse(resultList.get(0)); + } } } diff --git a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/job/RewardStatusVerifierJob.java b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/job/RewardStatusVerifierJob.java index 112e7fad3..f37a28623 100644 --- a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/job/RewardStatusVerifierJob.java +++ b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/job/RewardStatusVerifierJob.java @@ -63,7 +63,7 @@ public RewardStatusVerifierJob() { } @Override - public void execute(JobExecutionContext context) throws JobExecutionException { + public void execute(JobExecutionContext context) throws JobExecutionException { // NOSONAR ExoContainer currentContainer = ExoContainerContext.getCurrentContainer(); ExoContainerContext.setCurrentContainer(container); RequestLifeCycle.begin(this.container); @@ -78,15 +78,19 @@ public void execute(JobExecutionContext context) throws JobExecutionException { Iterator rewardPeriodsIterator = rewardPeriodsInProgress.iterator(); while (rewardPeriodsIterator.hasNext()) { RewardPeriod rewardPeriod = rewardPeriodsIterator.next(); - RewardReport rewardReport = getRewardReportService().computeRewards(rewardPeriod.getPeriodMedianDate()); - if (rewardReport == null) { - continue; + if (!getRewardReportService().isRewardSendingInProgress()) { + // Avoid saving rewards while transaction status storage is in + // progress + RewardReport rewardReport = getRewardReportService().computeRewards(rewardPeriod.getPeriodMedianDate()); + if (rewardReport != null) { + if (rewardReport.isCompletelyProceeded()) { + getListenerService().broadcast(REWARD_SUCCESS_EVENT_NAME, rewardReport, null); + getRewardReportService().saveRewardReport(rewardReport); + } else if (rewardReport.getPendingTransactionCount() == 0 && rewardReport.getTokensSent() == 0) { + getRewardReportService().saveRewardReport(rewardReport); + } + } } - if (rewardReport.isCompletelyProceeded()) { - getListenerService().broadcast(REWARD_SUCCESS_EVENT_NAME, rewardReport, null); - rewardPeriodsIterator.remove(); - } - getRewardReportService().saveRewardReport(rewardReport); } } } catch (Exception e) { diff --git a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardReportService.java b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardReportService.java index f4012d333..cd53f5624 100644 --- a/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardReportService.java +++ b/wallet-reward-services/src/main/java/org/exoplatform/wallet/reward/service/WalletRewardReportService.java @@ -73,12 +73,16 @@ import org.exoplatform.wallet.service.WalletAccountService; import org.exoplatform.wallet.service.WalletTokenAdminService; +import lombok.Setter; + /** * A service to manage reward reports */ public class WalletRewardReportService implements RewardReportService { - private static final Log LOG = ExoLogger.getLogger(WalletRewardReportService.class); + private static final Log LOG = ExoLogger.getLogger(WalletRewardReportService.class); + + private static final String EMPTY_SETTINGS = "Error computing rewards using empty settings"; private final WalletAccountService walletAccountService; @@ -90,6 +94,9 @@ public class WalletRewardReportService implements RewardReportService { private final WalletRewardReportStorage rewardReportStorage; + @Setter + private boolean rewardSendingInProgress; + public WalletRewardReportService(WalletAccountService walletAccountService, RewardSettingsService rewardSettingsService, RewardTeamService rewardTeamService, @@ -182,7 +189,17 @@ public void sendRewards(LocalDate date, String username) throws Exception { // N LOG.warn("Error while sending reward transaction for user '{}'", walletReward.getWallet().getName(), e); } } - rewardReportStorage.saveRewardReport(rewardReport); + this.rewardSendingInProgress = true; + try { + rewardReportStorage.saveRewardReport(rewardReport); + } finally { + this.rewardSendingInProgress = false; + } + } + + @Override + public boolean isRewardSendingInProgress() { + return rewardSendingInProgress; } @Override @@ -218,7 +235,7 @@ public RewardReport computeRewardsByUser(LocalDate date, long userIdentityId) { public RewardReport getRewardReport(LocalDate date) { RewardSettings rewardSettings = rewardSettingsService.getSettings(); if (rewardSettings == null) { - throw new IllegalStateException("Error computing rewards using empty settings"); + throw new IllegalStateException(EMPTY_SETTINGS); } if (rewardSettings.getPeriodType() == null) { throw new IllegalStateException("Error computing rewards using empty period type"); @@ -554,7 +571,7 @@ private void buildNoPoolUsers(Map earnedPoints, List t RewardTeamMember rewardTeamMember = new RewardTeamMember(); rewardTeamMember.setIdentityId(identityId); return rewardTeamMember; - }).collect(Collectors.toList()); + }).toList(); noPoolRewardTeam.setMembers(noPoolRewardTeamList); noPoolRewardTeam.setId(0L); noPoolRewardTeam.setRewardType(RewardBudgetType.COMPUTED); diff --git a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/job/WalletRewardJobTest.java b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/job/WalletRewardJobTest.java index a612de87d..df88ff133 100644 --- a/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/job/WalletRewardJobTest.java +++ b/wallet-reward-services/src/test/java/org/exoplatform/wallet/reward/job/WalletRewardJobTest.java @@ -48,11 +48,9 @@ import org.exoplatform.wallet.model.transaction.TransactionDetail; import org.exoplatform.wallet.reward.BaseWalletRewardTest; import org.exoplatform.wallet.reward.api.RewardPlugin; -import org.exoplatform.wallet.reward.service.RewardTeamService; import org.exoplatform.wallet.reward.service.WalletRewardReportService; import org.exoplatform.wallet.reward.service.WalletRewardSettingsService; import org.exoplatform.wallet.reward.service.WalletRewardTeamService; -import org.exoplatform.wallet.reward.storage.WalletRewardReportStorage; import org.exoplatform.wallet.service.WalletAccountService; import org.exoplatform.wallet.service.WalletTokenAdminService; import org.exoplatform.wallet.service.WalletTransactionService; @@ -80,16 +78,10 @@ public void testGetRewardPlugins() { @Test public void testSendRewards() throws Exception { - WalletAccountService walletAccountService = getService(WalletAccountService.class); WalletRewardSettingsService rewardSettingsService = getService(WalletRewardSettingsService.class); - RewardTeamService rewardTeamService = getService(RewardTeamService.class); WalletTransactionService walletTransactionService = getService(WalletTransactionService.class); - WalletRewardReportStorage rewardReportStorage = getService(WalletRewardReportStorage.class); - WalletRewardReportService walletRewardService = new WalletRewardReportService(walletAccountService, - rewardSettingsService, - rewardTeamService, - rewardReportStorage); + WalletRewardReportService walletRewardService = getService(WalletRewardReportService.class); WalletTokenAdminService tokenAdminService = Mockito.mock(WalletTokenAdminService.class); resetTokenAdminService(walletTransactionService, tokenAdminService, true, false); @@ -189,6 +181,18 @@ public void testSendRewards() throws Exception { adminWallet.setTokenBalance(3d); adminWallet.setEnabled(true); + rewardPeriodsInProgress = walletRewardService.getRewardPeriodsInProgress(); + assertNotNull(rewardPeriodsInProgress); + assertEquals(1, rewardPeriodsInProgress.size()); + + walletRewardService.setRewardSendingInProgress(true); + rewardReportNotificationJob.execute(null); + + rewardPeriodsInProgress = walletRewardService.getRewardPeriodsInProgress(); + assertNotNull(rewardPeriodsInProgress); + assertEquals(1, rewardPeriodsInProgress.size()); + + walletRewardService.setRewardSendingInProgress(false); rewardReportNotificationJob.execute(null); rewardPeriodsInProgress = walletRewardService.getRewardPeriodsInProgress();