diff --git a/src/main/java/com/xuxd/kafka/console/beans/dto/AlterClientQuotaDTO.java b/src/main/java/com/xuxd/kafka/console/beans/dto/AlterClientQuotaDTO.java index 07a367d..21ec987 100644 --- a/src/main/java/com/xuxd/kafka/console/beans/dto/AlterClientQuotaDTO.java +++ b/src/main/java/com/xuxd/kafka/console/beans/dto/AlterClientQuotaDTO.java @@ -11,6 +11,8 @@ import java.util.List; @Data public class AlterClientQuotaDTO { + private String type; + private List types; private List names; @@ -20,4 +22,6 @@ public class AlterClientQuotaDTO { private String producerRate; private String requestPercentage; + + private List deleteConfigs; } diff --git a/src/main/java/com/xuxd/kafka/console/beans/vo/ClientQuotaEntityVO.java b/src/main/java/com/xuxd/kafka/console/beans/vo/ClientQuotaEntityVO.java index 7fd59ff..d53a0a5 100644 --- a/src/main/java/com/xuxd/kafka/console/beans/vo/ClientQuotaEntityVO.java +++ b/src/main/java/com/xuxd/kafka/console/beans/vo/ClientQuotaEntityVO.java @@ -68,7 +68,7 @@ public class ClientQuotaEntityVO { double _1kb = 1024; double _1mb = 1024 * _1kb; if (value < _1kb) { - return value + "Byte"; + return value + " Byte"; } if (value < _1mb) { return String.format("%.1f KB", (value / _1kb)); diff --git a/src/main/java/com/xuxd/kafka/console/controller/ClientQuotaController.java b/src/main/java/com/xuxd/kafka/console/controller/ClientQuotaController.java index 144b42a..bce4f05 100644 --- a/src/main/java/com/xuxd/kafka/console/controller/ClientQuotaController.java +++ b/src/main/java/com/xuxd/kafka/console/controller/ClientQuotaController.java @@ -5,10 +5,7 @@ import com.xuxd.kafka.console.beans.dto.AlterClientQuotaDTO; import com.xuxd.kafka.console.beans.dto.QueryClientQuotaDTO; import com.xuxd.kafka.console.service.ClientQuotaService; import org.apache.commons.collections.CollectionUtils; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; /** * @author: xuxd @@ -38,4 +35,14 @@ public class ClientQuotaController { } return clientQuotaService.alterClientQuotaConfigs(request); } + + @DeleteMapping + public Object deleteClientQuotaConfigs(@RequestBody AlterClientQuotaDTO request) { + if (CollectionUtils.isEmpty(request.getTypes()) + || CollectionUtils.isEmpty(request.getNames()) + || request.getTypes().size() != request.getNames().size()) { + return ResponseData.create().failed("types length and names length is invalid."); + } + return clientQuotaService.deleteClientQuotaConfigs(request); + } } diff --git a/src/main/java/com/xuxd/kafka/console/service/ClientQuotaService.java b/src/main/java/com/xuxd/kafka/console/service/ClientQuotaService.java index 301ddfc..a50f3b7 100644 --- a/src/main/java/com/xuxd/kafka/console/service/ClientQuotaService.java +++ b/src/main/java/com/xuxd/kafka/console/service/ClientQuotaService.java @@ -13,4 +13,6 @@ public interface ClientQuotaService { ResponseData getClientQuotaConfigs(List types, List names); ResponseData alterClientQuotaConfigs(AlterClientQuotaDTO request); + + ResponseData deleteClientQuotaConfigs(AlterClientQuotaDTO request); } diff --git a/src/main/java/com/xuxd/kafka/console/service/impl/ClientQuotaServiceImpl.java b/src/main/java/com/xuxd/kafka/console/service/impl/ClientQuotaServiceImpl.java index 0dcf3a6..884e59a 100644 --- a/src/main/java/com/xuxd/kafka/console/service/impl/ClientQuotaServiceImpl.java +++ b/src/main/java/com/xuxd/kafka/console/service/impl/ClientQuotaServiceImpl.java @@ -6,7 +6,9 @@ import com.xuxd.kafka.console.beans.vo.ClientQuotaEntityVO; import com.xuxd.kafka.console.service.ClientQuotaService; import kafka.console.ClientQuotaConsole; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.kafka.common.config.internals.QuotaConfigs; import org.apache.kafka.common.quota.ClientQuotaEntity; import org.springframework.stereotype.Service; @@ -24,10 +26,22 @@ public class ClientQuotaServiceImpl implements ClientQuotaService { private final Map typeDict = new HashMap<>(); + private final Map configDict = new HashMap<>(); + + private final String USER = "user"; + private final String CLIENT_ID = "client-id"; + private final String IP = "ip"; + private final String USER_CLIENT = "user&client-id"; + { - typeDict.put("user", ClientQuotaEntity.USER); - typeDict.put("client-id", ClientQuotaEntity.CLIENT_ID); - typeDict.put("ip", ClientQuotaEntity.IP); + typeDict.put(USER, ClientQuotaEntity.USER); + typeDict.put(CLIENT_ID, ClientQuotaEntity.CLIENT_ID); + typeDict.put(IP, ClientQuotaEntity.IP); + typeDict.put(USER_CLIENT, USER_CLIENT); + + configDict.put("producerRate", QuotaConfigs.PRODUCER_BYTE_RATE_OVERRIDE_CONFIG); + configDict.put("consumerRate", QuotaConfigs.CONSUMER_BYTE_RATE_OVERRIDE_CONFIG); + configDict.put("requestPercentage", QuotaConfigs.REQUEST_PERCENTAGE_OVERRIDE_CONFIG); } public ClientQuotaServiceImpl(ClientQuotaConsole clientQuotaConsole) { @@ -65,9 +79,84 @@ public class ClientQuotaServiceImpl implements ClientQuotaService { @Override public ResponseData alterClientQuotaConfigs(AlterClientQuotaDTO request) { - return ResponseData.create().failed(); + if (StringUtils.isEmpty(request.getType()) || !typeDict.containsKey(request.getType())) { + return ResponseData.create().failed("Unknown type."); + } + + List types = new ArrayList<>(); + List names = new ArrayList<>(); + parseTypesAndNames(request, types, names, request.getType()); + Map configsToBeAddedMap = new HashMap<>(); + + if (StringUtils.isNotEmpty(request.getProducerRate())) { + configsToBeAddedMap.put(QuotaConfigs.PRODUCER_BYTE_RATE_OVERRIDE_CONFIG, String.valueOf(Math.floor(Double.valueOf(request.getProducerRate())))); + } + if (StringUtils.isNotEmpty(request.getConsumerRate())) { + configsToBeAddedMap.put(QuotaConfigs.CONSUMER_BYTE_RATE_OVERRIDE_CONFIG, String.valueOf(Math.floor(Double.valueOf(request.getConsumerRate())))); + } + if (StringUtils.isNotEmpty(request.getRequestPercentage())) { + configsToBeAddedMap.put(QuotaConfigs.REQUEST_PERCENTAGE_OVERRIDE_CONFIG, String.valueOf(Math.floor(Double.valueOf(request.getRequestPercentage())))); + } + + clientQuotaConsole.addQuotaConfigs(types, names, configsToBeAddedMap); + if (CollectionUtils.isNotEmpty(request.getDeleteConfigs())) { + List delete = request.getDeleteConfigs().stream().map(key -> configDict.get(key)).collect(Collectors.toList()); + clientQuotaConsole.deleteQuotaConfigs(types, names, delete); + } + return ResponseData.create().success(); } + @Override + public ResponseData deleteClientQuotaConfigs(AlterClientQuotaDTO request) { + if (StringUtils.isEmpty(request.getType()) || !typeDict.containsKey(request.getType())) { + return ResponseData.create().failed("Unknown type."); + } + List types = new ArrayList<>(); + List names = new ArrayList<>(); + parseTypesAndNames(request, types, names, request.getType()); + List configs = new ArrayList<>(); + configs.add(QuotaConfigs.PRODUCER_BYTE_RATE_OVERRIDE_CONFIG); + configs.add(QuotaConfigs.CONSUMER_BYTE_RATE_OVERRIDE_CONFIG); + configs.add(QuotaConfigs.REQUEST_PERCENTAGE_OVERRIDE_CONFIG); + clientQuotaConsole.deleteQuotaConfigs(types, names, configs); + return ResponseData.create().success(); + } + private void parseTypesAndNames(AlterClientQuotaDTO request, List types, List names, String type) { + switch (request.getType()) { + case USER: + getTypesAndNames(request, types, names, USER); + break; + case CLIENT_ID: + getTypesAndNames(request, types, names, CLIENT_ID); + break; + case IP: + getTypesAndNames(request, types, names, IP); + break; + case USER_CLIENT: + getTypesAndNames(request, types, names, USER); + getTypesAndNames(request, types, names, CLIENT_ID); + break; + } + } + + private void getTypesAndNames(AlterClientQuotaDTO request, List types, List names, String type) { + int index = -1; + for (int i = 0; i < request.getTypes().size(); i++) { + if (type.equals(request.getTypes().get(i))) { + index = i; + break; + } + } + if (index < 0) { + throw new IllegalArgumentException("Does not contain the type:" + type); + } + types.add(request.getTypes().get(index)); + if (CollectionUtils.isNotEmpty(request.getNames()) && request.getNames().size() > index) { + names.add(request.getNames().get(index)); + } else { + names.add(""); + } + } } diff --git a/ui/src/utils/api.js b/ui/src/utils/api.js index 7d54ca1..31b747f 100644 --- a/ui/src/utils/api.js +++ b/ui/src/utils/api.js @@ -303,4 +303,8 @@ export const KafkaClientQuotaApi = { url: "/client/quota", method: "post", }, + deleteClientQuotaConfigs: { + url: "/client/quota", + method: "delete", + }, }; \ No newline at end of file diff --git a/ui/src/views/quota/AddQuotaConfig.vue b/ui/src/views/quota/AddQuotaConfig.vue index 2a3320c..d545463 100644 --- a/ui/src/views/quota/AddQuotaConfig.vue +++ b/ui/src/views/quota/AddQuotaConfig.vue @@ -1,3 +1,4 @@ +