From 547af9dda19695c6754f44770211a38bebbfd633 Mon Sep 17 00:00:00 2001 From: yangzl Date: Tue, 10 Sep 2024 15:44:46 +0800 Subject: [PATCH] feat: add determine single namespace item num limit logic --- .../adminservice/controller/ItemController.java | 12 ++++++++++-- .../framework/apollo/biz/config/BizConfig.java | 8 ++++++++ .../apollo/biz/repository/ItemRepository.java | 4 ++++ .../framework/apollo/biz/service/ItemService.java | 4 ++++ .../apollo/biz/service/ItemSetService.java | 14 +++++++++++++- 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/ItemController.java b/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/ItemController.java index 2e7e25d5912..6d0c41c52fe 100644 --- a/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/ItemController.java +++ b/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/ItemController.java @@ -17,6 +17,7 @@ package com.ctrip.framework.apollo.adminservice.controller; import com.ctrip.framework.apollo.adminservice.aop.PreAcquireNamespaceLock; +import com.ctrip.framework.apollo.biz.config.BizConfig; import com.ctrip.framework.apollo.biz.entity.Commit; import com.ctrip.framework.apollo.biz.entity.Item; import com.ctrip.framework.apollo.biz.entity.Namespace; @@ -57,13 +58,14 @@ public class ItemController { private final NamespaceService namespaceService; private final CommitService commitService; private final ReleaseService releaseService; + private final BizConfig bizConfig; - - public ItemController(final ItemService itemService, final NamespaceService namespaceService, final CommitService commitService, final ReleaseService releaseService) { + public ItemController(final ItemService itemService, final NamespaceService namespaceService, final CommitService commitService, final ReleaseService releaseService, final BizConfig bizConfig) { this.itemService = itemService; this.namespaceService = namespaceService; this.commitService = commitService; this.releaseService = releaseService; + this.bizConfig = bizConfig; } @PreAcquireNamespaceLock @@ -77,6 +79,12 @@ public ItemDTO create(@PathVariable("appId") String appId, if (managedEntity != null) { throw BadRequestException.itemAlreadyExists(entity.getKey()); } + + int itemCount = itemService.findNonEmptyItemCount(entity.getNamespaceId()) ; + if(itemCount >= bizConfig.itemNumLimit()) { + throw new BadRequestException("current namespace item count=[" + itemCount + "], single namespace max allow count=[ "+ bizConfig.itemNumLimit() + "]"); + } + entity = itemService.save(entity); dto = BeanUtils.transform(ItemDTO.class, entity); commitService.createCommit(appId, clusterName, namespaceName, new ConfigChangeContentBuilder().createItem(entity).build(), diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/config/BizConfig.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/config/BizConfig.java index 2652995f582..947fbcb395b 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/config/BizConfig.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/config/BizConfig.java @@ -36,6 +36,9 @@ public class BizConfig extends RefreshableConfig { private static final int DEFAULT_ITEM_KEY_LENGTH = 128; private static final int DEFAULT_ITEM_VALUE_LENGTH = 20000; + + private static final int DEFAULT_MAX_ITEM_NUM = 10000; + private static final int DEFAULT_APPNAMESPACE_CACHE_REBUILD_INTERVAL = 60; //60s private static final int DEFAULT_GRAY_RELEASE_RULE_SCAN_INTERVAL = 60; //60s private static final int DEFAULT_APPNAMESPACE_CACHE_SCAN_INTERVAL = 1; //1s @@ -99,6 +102,11 @@ public int itemValueLengthLimit() { return checkInt(limit, 5, Integer.MAX_VALUE, DEFAULT_ITEM_VALUE_LENGTH); } + public int itemNumLimit() { + int limit = getIntProperty("item.num.limit", DEFAULT_MAX_ITEM_NUM); + return checkInt(limit, 5, Integer.MAX_VALUE, DEFAULT_MAX_ITEM_NUM); + } + public Map namespaceValueLengthLimitOverride() { String namespaceValueLengthOverrideString = getValue("namespace.value.length.limit.override"); Map namespaceValueLengthOverride = Maps.newHashMap(); diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ItemRepository.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ItemRepository.java index d482ce63e97..d8aada2a8f5 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ItemRepository.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ItemRepository.java @@ -23,6 +23,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; import java.util.Date; import java.util.List; @@ -47,4 +48,7 @@ public interface ItemRepository extends PagingAndSortingRepository { @Query("update Item set IsDeleted = true, DeletedAt = ROUND(UNIX_TIMESTAMP(NOW(4))*1000), DataChange_LastModifiedBy = ?2 where NamespaceId = ?1 and IsDeleted = false") int deleteByNamespaceId(long namespaceId, String operator); + @Query("select count(*) from Item where namespaceId = :namespaceId and key <>''") + int countByNamespaceIdAndFilterKeyEmpty(@Param("namespaceId")long namespaceId) ; + } diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemService.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemService.java index 7dffa366c5e..343cfa82d58 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemService.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemService.java @@ -137,6 +137,10 @@ public List findItemsModifiedAfterDate(long namespaceId, Date date) { return itemRepository.findByNamespaceIdAndDataChangeLastModifiedTimeGreaterThan(namespaceId, date); } + public int findNonEmptyItemCount (long namespaceId) { + return itemRepository.countByNamespaceIdAndFilterKeyEmpty(namespaceId) ; + } + public Page findItemsByKey(String key, Pageable pageable) { return itemRepository.findByKey(key, pageable); } diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemSetService.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemSetService.java index f1559d2643d..76926d33062 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemSetService.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemSetService.java @@ -16,6 +16,7 @@ */ package com.ctrip.framework.apollo.biz.service; +import com.ctrip.framework.apollo.biz.config.BizConfig; import com.ctrip.framework.apollo.biz.entity.Audit; import com.ctrip.framework.apollo.biz.entity.Item; import com.ctrip.framework.apollo.biz.entity.Namespace; @@ -38,16 +39,19 @@ public class ItemSetService { private final CommitService commitService; private final ItemService itemService; private final NamespaceService namespaceService; + private final BizConfig bizConfig; public ItemSetService( final AuditService auditService, final CommitService commitService, final ItemService itemService, - final NamespaceService namespaceService) { + final NamespaceService namespaceService, + final BizConfig bizConfig) { this.auditService = auditService; this.commitService = commitService; this.itemService = itemService; this.namespaceService = namespaceService; + this.bizConfig = bizConfig; } @Transactional @@ -64,6 +68,14 @@ public ItemChangeSets updateSet(String appId, String clusterName, throw NotFoundException.namespaceNotFound(appId, clusterName, namespaceName); } + int itemCount = itemService.findNonEmptyItemCount(namespace.getId()); + int createItemCount = (int) changeSet.getCreateItems().stream().filter(item -> !"".equals(item.getKey())).count(); + int deleteItemCount = (int) changeSet.getDeleteItems().stream().filter(item -> !"".equals(item.getKey())).count(); + itemCount = itemCount + createItemCount - deleteItemCount; + if(itemCount >= bizConfig.itemNumLimit()) { + throw new BadRequestException("current namespace item count=[" + itemCount + "], single namespace max allow count=[ "+ bizConfig.itemNumLimit() + "]"); + } + String operator = changeSet.getDataChangeLastModifiedBy(); ConfigChangeContentBuilder configChangeContentBuilder = new ConfigChangeContentBuilder();