From ee6defe5d2d5a767ac6d38148fd2995850c9999b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=99=93=E4=B8=9C?= <763795151@qq.com> Date: Sat, 4 Feb 2023 21:28:51 +0800 Subject: [PATCH] =?UTF-8?q?=E9=99=90=E6=B5=81=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AFID=E6=9F=A5=E8=AF=A2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../console/beans/vo/ClientQuotaEntityVO.java | 36 +++- .../console/interceptor/ContextSetFilter.java | 24 ++- .../console/service/ClientQuotaService.java | 6 +- .../service/impl/ClientQuotaServiceImpl.java | 21 ++- .../console/scala/ClientQuotaConsoleTest.java | 11 +- ui/package-lock.json | 160 ++++++++-------- ui/src/views/quota/AddQuotaConfig.vue | 169 +++++++++++++++++ ui/src/views/quota/ClientIDQuota.vue | 175 ++++++++++++++++++ ui/src/views/quota/ClientQuota.vue | 28 +-- ui/src/views/quota/QuotaList.vue | 56 ++++++ 10 files changed, 549 insertions(+), 137 deletions(-) create mode 100644 ui/src/views/quota/AddQuotaConfig.vue create mode 100644 ui/src/views/quota/ClientIDQuota.vue create mode 100644 ui/src/views/quota/QuotaList.vue 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 a4dc5ec..7fd59ff 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 @@ -1,6 +1,7 @@ package com.xuxd.kafka.console.beans.vo; import lombok.Data; +import org.apache.commons.lang3.StringUtils; import org.apache.kafka.common.config.internals.QuotaConfigs; import org.apache.kafka.common.quota.ClientQuotaEntity; @@ -43,10 +44,39 @@ public class ClientQuotaEntityVO { break; } }); - entityVO.setConsumerRate(config.getOrDefault(QuotaConfigs.CONSUMER_BYTE_RATE_OVERRIDE_CONFIG, "").toString()); - entityVO.setProducerRate(config.getOrDefault(QuotaConfigs.PRODUCER_BYTE_RATE_OVERRIDE_CONFIG, "").toString()); + entityVO.setConsumerRate(convert(config.getOrDefault(QuotaConfigs.CONSUMER_BYTE_RATE_OVERRIDE_CONFIG, ""))); + entityVO.setProducerRate(convert(config.getOrDefault(QuotaConfigs.PRODUCER_BYTE_RATE_OVERRIDE_CONFIG, ""))); entityVO.setRequestPercentage(config.getOrDefault(QuotaConfigs.REQUEST_PERCENTAGE_OVERRIDE_CONFIG, "").toString()); - return entityVO; } + + + public static String convert(Object num) { + if (num == null) { + return null; + } + + if (num instanceof String) { + if ((StringUtils.isBlank((String) num))) { + return (String) num; + } + } + + if (num instanceof Number) { + Number number = (Number) num; + double value = number.doubleValue(); + double _1kb = 1024; + double _1mb = 1024 * _1kb; + if (value < _1kb) { + return value + "Byte"; + } + if (value < _1mb) { + return String.format("%.1f KB", (value / _1kb)); + } + if (value >= _1mb) { + return String.format("%.1f MB", (value / _1mb)); + } + } + return String.valueOf(num); + } } diff --git a/src/main/java/com/xuxd/kafka/console/interceptor/ContextSetFilter.java b/src/main/java/com/xuxd/kafka/console/interceptor/ContextSetFilter.java index 8b2ed58..cd5acf9 100644 --- a/src/main/java/com/xuxd/kafka/console/interceptor/ContextSetFilter.java +++ b/src/main/java/com/xuxd/kafka/console/interceptor/ContextSetFilter.java @@ -6,28 +6,25 @@ import com.xuxd.kafka.console.config.ContextConfig; import com.xuxd.kafka.console.config.ContextConfigHolder; import com.xuxd.kafka.console.dao.ClusterInfoMapper; import com.xuxd.kafka.console.utils.ConvertUtil; -import java.io.IOException; -import java.util.HashSet; -import java.util.Set; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.annotation.WebFilter; -import javax.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + /** * kafka-console-ui. * * @author xuxd * @date 2022-01-05 19:56:25 **/ -@WebFilter(filterName = "context-set-filter", urlPatterns = {"/acl/*","/user/*","/cluster/*","/config/*","/consumer/*","/message/*","/topic/*","/op/*"}) +@WebFilter(filterName = "context-set-filter", urlPatterns = {"/acl/*", "/user/*", "/cluster/*", "/config/*", "/consumer/*", "/message/*", "/topic/*", "/op/*", "/client/*"}) @Slf4j public class ContextSetFilter implements Filter { @@ -42,8 +39,9 @@ public class ContextSetFilter implements Filter { @Autowired private ClusterInfoMapper clusterInfoMapper; - @Override public void doFilter(ServletRequest req, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + @Override + public void doFilter(ServletRequest req, ServletResponse response, + FilterChain chain) throws IOException, ServletException { try { HttpServletRequest request = (HttpServletRequest) req; String uri = request.getRequestURI(); 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 2abd6b8..301ddfc 100644 --- a/src/main/java/com/xuxd/kafka/console/service/ClientQuotaService.java +++ b/src/main/java/com/xuxd/kafka/console/service/ClientQuotaService.java @@ -1,7 +1,7 @@ package com.xuxd.kafka.console.service; +import com.xuxd.kafka.console.beans.ResponseData; import com.xuxd.kafka.console.beans.dto.AlterClientQuotaDTO; -import com.xuxd.kafka.console.beans.vo.ClientQuotaEntityVO; import java.util.List; @@ -10,7 +10,7 @@ import java.util.List; */ public interface ClientQuotaService { - List getClientQuotaConfigs(List types, List names); + ResponseData getClientQuotaConfigs(List types, List names); - Object alterClientQuotaConfigs(AlterClientQuotaDTO request); + ResponseData alterClientQuotaConfigs(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 ae4f51b..0dcf3a6 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 @@ -35,34 +35,39 @@ public class ClientQuotaServiceImpl implements ClientQuotaService { } @Override - public List getClientQuotaConfigs(List types, List names) { + public ResponseData getClientQuotaConfigs(List types, List names) { List entityNames = names == null ? Collections.emptyList() : new ArrayList<>(names); List entityTypes = types.stream().map(e -> typeDict.get(e)).filter(e -> e != null).collect(Collectors.toList()); if (entityTypes.isEmpty() || entityTypes.size() != types.size()) { throw new IllegalArgumentException("types illegal."); } - boolean userWithClientFilterClientOnly = false; + boolean userAndClientFilterClientOnly = false; + // only type: [user and client-id], type.size == 2 if (entityTypes.size() == 2) { if (names.size() == 2 && StringUtils.isBlank(names.get(0)) && StringUtils.isNotBlank(names.get(1))) { - userWithClientFilterClientOnly = true; + userAndClientFilterClientOnly = true; } } Map> clientQuotasConfigs = clientQuotaConsole.getClientQuotasConfigs(entityTypes, - userWithClientFilterClientOnly ? Collections.emptyList() : entityNames); + userAndClientFilterClientOnly ? Collections.emptyList() : entityNames); List voList = clientQuotasConfigs.entrySet().stream().map(entry -> ClientQuotaEntityVO.from( entry.getKey(), entityTypes, entry.getValue())).collect(Collectors.toList()); - if (!userWithClientFilterClientOnly) { - return voList; + if (!userAndClientFilterClientOnly) { + return ResponseData.create().data(voList).success(); } - return voList.stream().filter(e -> names.get(1).equals(e.getClient())).collect(Collectors.toList()); + List list = voList.stream().filter(e -> names.get(1).equals(e.getClient())).collect(Collectors.toList()); + + return ResponseData.create().data(list).success(); } @Override - public Object alterClientQuotaConfigs(AlterClientQuotaDTO request) { + public ResponseData alterClientQuotaConfigs(AlterClientQuotaDTO request) { return ResponseData.create().failed(); } + + } diff --git a/src/test/java/com/xuxd/kafka/console/scala/ClientQuotaConsoleTest.java b/src/test/java/com/xuxd/kafka/console/scala/ClientQuotaConsoleTest.java index 414e622..4b82678 100644 --- a/src/test/java/com/xuxd/kafka/console/scala/ClientQuotaConsoleTest.java +++ b/src/test/java/com/xuxd/kafka/console/scala/ClientQuotaConsoleTest.java @@ -14,7 +14,7 @@ import java.util.Map; public class ClientQuotaConsoleTest { - String bootstrapServer = "10.1.18.222:9092"; + String bootstrapServer = "localhost:9092"; @Test void testGetClientQuotasConfigs() { @@ -38,8 +38,11 @@ public class ClientQuotaConsoleTest { Map configsToBeAddedMap = new HashMap<>(); configsToBeAddedMap.put(QuotaConfigs.PRODUCER_BYTE_RATE_OVERRIDE_CONFIG, "1024000000"); -// console.addQuotaConfigs(Arrays.asList(ClientQuotaEntity.USER), Arrays.asList("user-test"), configsToBeAddedMap); -// console.addQuotaConfigs(Arrays.asList(ClientQuotaEntity.USER), Arrays.asList(""), configsToBeAddedMap); - console.deleteQuotaConfigs(Arrays.asList(ClientQuotaEntity.CLIENT_ID), Arrays.asList(""), Arrays.asList(QuotaConfigs.CONSUMER_BYTE_RATE_OVERRIDE_CONFIG)); + console.addQuotaConfigs(Arrays.asList(ClientQuotaEntity.USER), Arrays.asList("user-test"), configsToBeAddedMap); + console.addQuotaConfigs(Arrays.asList(ClientQuotaEntity.USER), Arrays.asList(""), configsToBeAddedMap); + console.addQuotaConfigs(Arrays.asList(ClientQuotaEntity.CLIENT_ID), Arrays.asList(""), configsToBeAddedMap); + console.addQuotaConfigs(Arrays.asList(ClientQuotaEntity.CLIENT_ID), Arrays.asList("clientA"), configsToBeAddedMap); + console.addQuotaConfigs(Arrays.asList(ClientQuotaEntity.USER, ClientQuotaEntity.CLIENT_ID), Arrays.asList("", ""), configsToBeAddedMap); +// console.deleteQuotaConfigs(Arrays.asList(ClientQuotaEntity.CLIENT_ID), Arrays.asList(""), Arrays.asList(QuotaConfigs.CONSUMER_BYTE_RATE_OVERRIDE_CONFIG)); } } diff --git a/ui/package-lock.json b/ui/package-lock.json index 8e05f0c..ab54346 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1820,6 +1820,63 @@ "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=", "dev": true }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, "ssri": { "version": "8.0.1", "resolved": "https://registry.nlark.com/ssri/download/ssri-8.0.1.tgz", @@ -1828,6 +1885,28 @@ "requires": { "minipass": "^3.1.1" } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.8.3", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz", + "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + } } } }, @@ -12097,87 +12176,6 @@ } } }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.8.3", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz", - "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "vue-ref": { "version": "2.0.0", "resolved": "https://registry.npm.taobao.org/vue-ref/download/vue-ref-2.0.0.tgz", diff --git a/ui/src/views/quota/AddQuotaConfig.vue b/ui/src/views/quota/AddQuotaConfig.vue new file mode 100644 index 0000000..2a3320c --- /dev/null +++ b/ui/src/views/quota/AddQuotaConfig.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/ui/src/views/quota/ClientIDQuota.vue b/ui/src/views/quota/ClientIDQuota.vue new file mode 100644 index 0000000..658d873 --- /dev/null +++ b/ui/src/views/quota/ClientIDQuota.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/ui/src/views/quota/ClientQuota.vue b/ui/src/views/quota/ClientQuota.vue index d592c8b..9511e06 100644 --- a/ui/src/views/quota/ClientQuota.vue +++ b/ui/src/views/quota/ClientQuota.vue @@ -3,6 +3,7 @@ + @@ -18,39 +19,16 @@ diff --git a/ui/src/views/quota/QuotaList.vue b/ui/src/views/quota/QuotaList.vue new file mode 100644 index 0000000..ebcbd8e --- /dev/null +++ b/ui/src/views/quota/QuotaList.vue @@ -0,0 +1,56 @@ + + + + +